Asp.net mvc 3 MVC 3自定义模型绑定到平面形式变量结构
当请求包含表单变量的平面集合时,我很难让自定义模型绑定器工作 我有一个ViewModel类,它包含一个嵌套的ViewModel,例如Asp.net mvc 3 MVC 3自定义模型绑定到平面形式变量结构,asp.net-mvc-3,custom-model-binder,Asp.net Mvc 3,Custom Model Binder,当请求包含表单变量的平面集合时,我很难让自定义模型绑定器工作 我有一个ViewModel类,它包含一个嵌套的ViewModel,例如 public class ViewModel1 { public long Id { get; set; } public ViewModel2 NestedType { get; set; } } public class ViewModel2 { public string Name { get; set; } public
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
不是
有什么办法可以让它工作吗
提前谢谢
编辑:
为了澄清一点,我的控制器操作如下所示:
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());
注册的另一种可能性是在控制器的操作中使用属性
我认为这个决定比其他决定更具普遍性,但也较慢(因为反射)
帮助我的ref:.你的意思是,通过JQuery Ajax表单提交,在Post Action方法中,你试图通过表单集合获取Nested2.Name?简而言之,是的,这是正确的,谢谢你,但我希望在我的控制器操作代码之前,我可以在模型绑定期间使它工作。我对我的问题做了一些修改,最后还是用了这个问题,虽然不完美,但却是我能找到的最干净的解决方案。干杯。是的,我可以这么做,问题是那些视图模型只是示例,真实的模型有很多属性,所以方法签名会有点笨拙。另外,嵌套类型嵌套在应用程序其他位置的其他viewmodel类型中。谢谢你的回复,谢谢你的建议。我可以这样做,但随后必须在操作中指定viewmodel.NestedType=viewModel2,这有点笨拙。我希望自定义模型绑定器可以将功能包装在一个位置,因为这不是应用程序中出现嵌套viewmodel的唯一位置。不过谢谢你的帮助:)
ModelBinders.Binders.Add(typeof(ViewModel1), new CustomModelBinder());