简体   繁体   English

自定义模型活页夹不会触发

[英]Custom Model Binder does not fire

I have registered a custom model binder for MyList in global.asax. 我已经在global.asax中为MyList注册了自定义模型活页夹。 However the model binder does not fire for nested properties, for simple types it works fine. 但是,模型绑定程序不会为嵌套属性触发,对于简单类型,它可以正常工作。 In the example below, it fires for Index() but not does not fire for Index2() 在下面的示例中,它为Index()触发,但不为Index2()触发

Global.asax 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);
}

Code: 码:

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();
    }
}

Model binders are used to allow actions to accept complex object types as parameters. 模型绑定器用于允许操作接受复杂的对象类型作为参数。 These complex types should be generated via POST requests, for example, by submitting a form. 这些复杂类型应通过POST请求生成,例如,提交表单。 If you have a highly complex object that cannot be binded by the default model binder (or it wouldn't be effective), you can use custom model binders. 如果您有一个非常复杂的对象,无法通过默认模型联编程序进行绑定(或者无效),则可以使用自定义模型联编程序。

To answer your question: if you don't add a custom model binder for the MyListWrapper class too, the BindModel(of the MyListBinder) won't be called in a GET request, this is how ASP.NET MVC works. 回答您的问题:如果您也没有为MyListWrapper类添加自定义模型绑定程序,则GET请求中将不会调用BindModel( MyListBinder) ,这就是ASP.NET MVC的工作方式。 However, if you modify your code by adding a POST action with the MyListWrapper parameter, you can see that the BindModel method is called properly. 但是,如果通过添加带有MyListWrapper参数的POST动作来修改代码,则可以看到BindModel方法已正确调用。

[HttpGet]
public ActionResult Index2()  // ModelBinder doesn't fire
{
    return View();
}

[HttpPost]
public ActionResult Index2(MyListWrapper wrapper) // ModelBinder fires
{
    return View();
}

And the Index2 view 和Index2视图

@model fun.web.MyListWrapper

@using (Html.BeginForm())
{
    @Html.HiddenFor(m => m.listItems)
    <input type="submit" value="Submit" />
}

If you'd like "control" the action parameters in a GET request, you should use action filters . 如果您想“控制” GET请求中的操作参数,则应使用操作过滤器

You defined binder for MyList , so it triggers only when action method input parameter is of type MyList . 您的定义粘结剂MyList ,所以它触发只有当操作方法输入参数的类型为MyList

ModelBinders.Binders.Add(typeof(MyList), new MyListBinder());

If you want model binder to trigger even when your MyList is nested into other model, you have to do this: 如果即使在MyList嵌套到其他模型中时也要触发模型联编程序,则必须执行以下操作:

[ModelBinder(typeof(MyListBinder))] 
public class MyList
{
    public List<int> items { get; set; }
}

Then, model binder triggers whenever it encounters MyList type, even when it's nested. 然后,每当遇到MyList类型时,即使它是嵌套的,模型绑定器也会触发。

Add this to your global: 将此添加到您的全局:

ModelBinders.Binders.Add(typeof(MyListWrapper), new MyListWrapperBinder());

And then create a MyListWrapperBinder that can handle the binding. 然后创建一个可以处理绑定的MyListWrapperBinder。

Your model binder is matched with your MyList class, not with MyListWrapper. 您的模型联编程序与MyList类而不是MyListWrapper匹配。 MyListBinder is only used with MyList class or a class which inherited from MyClass. MyListBinder仅与MyList类或从MyClass继承的类一起使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM