15

我已经在 global.asax 中为 MyList 注册了一个自定义模型绑定器。然而,模型绑定器不会为嵌套属性触发,对于简单类型它可以正常工作。在下面的示例中,它会为 Index() 触发,但不会为 Index2() 触发

全球.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();
    }
}
4

4 回答 4

2

模型绑定器用于允许操作接受复杂对象类型作为参数。这些复杂类型应该通过 POST 请求生成,例如,通过提交表单。如果您有一个无法被默认模型绑定器绑定的高度复杂的对象(或者它不会有效),您可以使用自定义模型绑定器。

回答您的问题: 如果您也没有为MyListWrapper该类添加自定义模型绑定器,则不会在 GET 请求中调用 BindModel( 的MyListBinder),这就是 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 请求中的操作参数,您应该使用操作过滤器

于 2013-04-05T07:40:09.960 回答
2

您定义了 binder for MyList,因此仅当 action 方法输入参数为 type 时才会触发MyList

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

如果您希望模型绑定器即使MyList嵌套到其他模型中也能触发,您必须这样做:

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

然后,模型绑定器在遇到MyList类型时触发,即使它是嵌套的。

于 2013-04-11T23:01:26.377 回答
1

将此添加到您的全局:

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

然后创建一个可以处理绑定的 MyListWrapperBinder。

于 2013-04-11T20:29:46.783 回答
0

您的模型绑定器与您的 MyList 类匹配,而不是与 MyListWrapper。MyListBinder 仅与 MyList 类或从 MyClass 继承的类一起使用。

于 2013-04-05T07:12:40.713 回答