当请求包含平面的表单变量集合时,我很难获得自定义模型绑定器。
我有一个包含嵌套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()。
答案 0 :(得分:1)
试试这个:
var viewModel = new ViewModel1();
UpdateModel(viewModel.NestedType);
答案 1 :(得分:1)
不是最佳解决方案,但您可以为该类型添加另一个参数:
public ActionResult GridEditRow(ViewModel1 viewModel, ViewModel2 viewModel2)
这应绑定Name属性,即使它没有正确的前缀。
答案 2 :(得分:0)
您可以通过以下方式更改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 )
}
答案 3 :(得分:0)
我遇到过类似的问题。正如您所认为的那样,可能的决定之一是自定义模型绑定器。虽然问题很老,但我会把答案放在这里(因为为什么不呢?)。因此,自定义模型绑定器的代码如下。
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。