MVC 3自定义模型绑定到平面形式变量结构



当请求包含表单变量的平面集合时,我很难让自定义模型绑定器工作。

我有一个ViewModel类,它包含一个嵌套的ViewModel,例如

public class ViewModel1
{
    public long Id { get; set; }
    public ViewModel2 NestedType { get; set; }
}
public class ViewModel2
{
    public string Name { get; set; }
    public string Surname { get; set; }
}

我的问题是,如果我使用Fiddler提交一个表单变量为NestedType.Name的请求,那么我的自定义模型绑定器执行得很好,然而,我必须处理的请求超出了我的控制范围,在这种情况下,它是通过JQGrid实例的ajax请求发布的,并且是"平面"的,即

Id=5
Name=firstname
Surname=surname

不是

Id=5
NestedType.Name=firstname
NestedType.Surname=surname

有什么办法让它发挥作用吗?

提前谢谢。

编辑:

为了澄清一点,我的控制器操作如下:

public ActionResult GridEditRow(ViewModel1 viewModel)

如下所述,我宁愿在执行控制器代码之前启动自定义绑定器,而不是调用TryUpdateModel()。

试试这个:

var viewModel = new ViewModel1();
UpdateModel(viewModel.NestedType);

不是最好的解决方案,但您可以为该类型添加另一个参数:

public ActionResult GridEditRow(ViewModel1 viewModel, ViewModel2 viewModel2)

这应该绑定Name属性,即使它没有正确的前缀。

您可以通过以下方式更改ActionResult:

public ActionResult GridEditRow(int id, string firstname, string surname)
{
  VewModel2 model2 = new VewModel2
{
Name  = firstname,
Surname = surname
}
  VewModel1 model1 = new VewModel1
{
Id = id,
NestedType  = model2 
}
return View(model1 )  
}

我也遇到过类似的问题。正如您所设想的,其中一个可能的决策是自定义模型绑定器。虽然这个问题已经过时了,但我将把我的答案放在这里(因为为什么不呢?)。因此,自定义模型绑定器的代码如下。

public class CustomModelBinder : DefaultModelBinder {
        protected override void BindProperty(
            ControllerContext controllerContext, 
            ModelBindingContext bindingContext, 
            System.ComponentModel.PropertyDescriptor propertyDescriptor) {
                if (bindingContext.ModelType == typeof(ViewModel1)) {
                    var name = propertyDescriptor.Name;
                    // Try to implement default binding.
                    // Also one could try base.BindProperty(...).
                    var value = bindingContext.ValueProvider.GetValue(name);
                    if (value != null)
                        propertyDescriptor.SetValue(bindingContext.Model, value.ConvertTo(propertyDescriptor.PropertyType));
                    // If the default binding is not working then search for nested values.
                    else {
                        value = bindingContext.ValueProvider.GetValue("NestedType." + name);
                        if(value != null)
                            propertyDescriptor.SetValue(bindingContext.Model, value.ConvertTo(propertyDescriptor.PropertyType));
                    }
                } else
                    base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
        }
    }

在Global.asax:中注册活页夹

ModelBinders.Binders.Add(typeof(ViewModel1), new CustomModelBinder());

注册的另一种可能性是在控制器的操作中使用属性。

我想这个决定比其他决定更普遍,但也更慢(因为反思)。

帮助过我的裁判:http://dotnetslackers.com/articles/aspnet/Understanding-ASP-NET-MVC-Model-Binding.aspx。

相关内容

  • 没有找到相关文章

最新更新