我在global.asax中为MyList注册了一个自定义模型绑定器。但是,模型绑定器不会触发嵌套属性,对于简单类型,它可以正常工作。在下面的示例中,它会触发Index()但不会触发Index2()
Global.asax中
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
ModelBinders.Binders.Add(typeof(MyList), new MyListBinder());
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
代码:
public class MyListBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
return new MyList();
}
}
public class MyList
{
public List<int> items { get; set; }
}
public class MyListWrapper
{
public MyList listItems { get; set; }
}
public class TestController : Controller
{
public ActionResult Index(MyList list) // ModelBinder fires :-)
{
return View();
}
public ActionResult Index2(MyListWrapper wrapper) // ModelBinder does not fire! :-(
{
return View();
}
}
答案 0 :(得分:2)
模型绑定器用于允许操作接受复杂对象类型作为参数。应通过POST请求生成这些复杂类型,例如,通过提交表单。如果您有一个高度复杂的对象,无法通过默认的模型绑定器绑定(或者它不会有效),您可以使用自定义模型绑定器。
回答您的问题:
如果您也没有为MyListWrapper
类添加自定义模型绑定器,则不会在GET请求中调用MyListBinder)
的BindModel,这就是ASP.NET MVC的工作方式。
但是,如果通过添加带有MyListWrapper
参数的POST操作来修改代码,则可以看到正确调用了BindModel方法。
[HttpGet]
public ActionResult Index2() // ModelBinder doesn't fire
{
return View();
}
[HttpPost]
public ActionResult Index2(MyListWrapper wrapper) // ModelBinder fires
{
return View();
}
和Index2视图
@model fun.web.MyListWrapper
@using (Html.BeginForm())
{
@Html.HiddenFor(m => m.listItems)
<input type="submit" value="Submit" />
}
如果您希望“控制”GET请求中的操作参数,则应使用action filters。
答案 1 :(得分:2)
您为MyList
定义了绑定器,因此仅当操作方法输入参数的类型为MyList
时才触发。
ModelBinders.Binders.Add(typeof(MyList), new MyListBinder());
如果您希望模型绑定器在您的MyList
嵌套到其他模型时触发,则必须执行此操作:
[ModelBinder(typeof(MyListBinder))]
public class MyList
{
public List<int> items { get; set; }
}
然后,模型绑定器会在遇到MyList
类型时触发,即使它是嵌套的。
答案 2 :(得分:1)
将此添加到您的全局:
ModelBinders.Binders.Add(typeof(MyListWrapper), new MyListWrapperBinder());
然后创建一个可以处理绑定的MyListWrapperBinder。
答案 3 :(得分:0)
您的模型绑定器与您的MyList类匹配,而不是与MyListWrapper匹配。 MyListBinder仅用于MyList类或从MyClass继承的类。