首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >运行中的多个模型参数

运行中的多个模型参数
EN

Stack Overflow用户
提问于 2019-06-10 11:22:34
回答 3查看 108关注 0票数 0

我有一个动作,它将用可选的querystring参数调用。但是,这些参数包含在不同的视图模型中。当我尝试将这些模型添加到我的参数列表中时,只有一个模型被填充,其他的总是空的。除了一个空的查询字符串,所有的模型都是用默认值实例化的。

不能选择嵌套这些模型,因为我不希望嵌套的属性名称在querystring中可见。因此,除非能以某种方式绕过这一点,否则这也是一个可行的解决方案。

我注意到,在创建DefaultModelBuilder的快速覆盖时,所有模型都会被解析,但最终结果仍然是实际上只分配了一个模型。

这是我的场景:

代码语言:javascript
复制
public ActionResult Index(ModelA ma, ModelB ba)
{
    return Content("ok");
}
代码语言:javascript
复制
public class ModelA
{
    public string Test { get; set; }
    public string Name { get; set; }
}

public class ModelB
{
    public int? SomeInteger { get; set; }
    public int? TestInteger { get; set; }
}

所需的查询字符串:

index?Test=Hi&SomeInteger=7

我想避免的是:

index?ModelA.Test=Hi&ModelB.SomeInteger=7

EN

回答 3

Stack Overflow用户

发布于 2019-06-10 21:38:58

您可以尝试创建一个将这两者结合在一起的类:

代码语言:javascript
复制
public class ModelPair
{
    public ModelA A { get; set; }
    public ModelB B { get; set; }
}

然后用

代码语言:javascript
复制
public ActionResult Index(ModelPair mp)
{
    return Content("ok");
}

你可以做?A.Test=blah&B.SomeInteger=42

票数 0
EN

Stack Overflow用户

发布于 2019-06-11 09:12:30

我最终致力于创建自己的自定义模型绑定器来执行递归绑定。只要属性名不被重用,这在我的模型中就不会发生,这解决了我不公开嵌套模型类的属性名的问题。

所以现在我有了如下的类结构:

代码语言:javascript
复制
public class ModelA
{
    public string Test { get; set; }
    public string Name { get; set; }
}

public class ModelB
{
    public int? SomeInteger { get; set; }
    public int? TestInteger { get; set; }
}

public class ViewModel
{
    public ModelA ModelA { get; set; }
    public ModelB ModelB { get; set; }
}

动作现在看起来是这样的

代码语言:javascript
复制
public ActionResult Index(ViewModel model)
{
    return Content("ok");
}

这样我就可以在不暴露丑陋的属性名称的情况下使用下面的查询字符串:

index?Test=Hi&SomeInteger=7&Name=Yep&TestInteger=72

当然,我还没有对此进行过长时间的测试,所以我不知道接下来会出现什么问题,但是所有的嵌套模型现在都正确地填充了来自querystring的数据,并且模型类可以很容易地重用:)

代码语言:javascript
复制
public class RecursiveModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var model = base.BindModel(controllerContext, bindingContext);
        if (model != null)
        {
            var properties = bindingContext.ModelType.GetProperties().Where(x => x.PropertyType.IsClass && !x.PropertyType.Equals(typeof(string)) );
            foreach(var property in properties)
            {
                var resursiveBindingContext = new ModelBindingContext(bindingContext)
                {
                    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, property.PropertyType)
                };
                var recursiveModel = BindModel(controllerContext, resursiveBindingContext);
                property.SetValue(model, recursiveModel);
            }
        }
        return model;
    }
}
票数 0
EN

Stack Overflow用户

发布于 2019-06-10 14:58:45

据我所知,默认的Model Binder不能做到这一点。我们必须实现自定义模型绑定器如下所示。

代码语言:javascript
复制
 public class CustomModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        var query = bindingContext.HttpContext.Request.Query;


        var modelb = new ModelB();
        if (query.TryGetValue($"{bindingContext.ModelName}.{nameof(modelb.SomeInteger)}", out var someInteger))
        {
            modelb.SomeInteger = Convert.ToInt32(JsonConvert.DeserializeObject(someInteger).ToString());
        }
        if (query.TryGetValue($"{bindingContext.ModelName}.{nameof(modelb.TestInteger)}", out var testInteger))
        {
            modelb.TestInteger = Convert.ToInt32(JsonConvert.DeserializeObject(testInteger).ToString());
        }

        bindingContext.Result = ModelBindingResult.Success(modelb);
        return Task.FromResult(modelb);
    }
}

在控制器操作中,我们可以使用绑定器,如下所示

代码语言:javascript
复制
   public IActionResult Index(ModelA modelA, [ModelBinder(typeof(CustomModelBinder))]ModelB modelB)
    {
        return Json(new {modelA, modelB});
    }

在querystring中,我们可以使用前缀来区分每个模型。

代码语言:javascript
复制
?modelA.test="MATests"&modelA.Name="modelANameValue"&modelB.SomeInteger="5"

请查找工作示例here on github

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56520125

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档