ModelBinder is not invoked

最后都变了- 提交于 2020-01-03 21:09:49

问题


Per my previous question, I implemented a model binder that maps /api/v1/widgets/1,2,3 to

// WidgetsController.cs: 
public ActionResult Show(IEnumerable<int> idArgs)
{

}

This was working for a while, but now it is not any longer. My ModelBinder is not even being invoked at all. When my action is invoked, idArgs has a value of the empty list, even if I set its default value to null in the route, which suggests to me that the default model binder thinks it's getting a value from somewhere. The only change I've made since last week when it was working is that previously, I had called my action ShowMany. Since then, I renamed it to Show. Can anyone help me figure out why my ModelBinder is not being invoked?

In global.asax.cs, I have

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes);
    ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());

    ModelBinders.Binders.Add(typeof(IEnumerable<int>), new IEnumerableOfIntCSVModelBinder());
}

And the route looks like this (I have verified that this route is being used):

context.MapRoute(
    "show",
    "api/{controller}/{idArgs}",
    new { action = "show" },
    new { httpMethod = new HttpMethodConstraint("GET"), idArgs = @"^(\d+,)+\d+,?$" }
);

Edit: I've tried messing messing with the routes some more, as well as commenting out the JsonValueProvider, and I'm still getting an empty array. In my controller, I can do

var ids = RouteData.Values["idArgs"];

and get the string "1,2,3". If only the framework would pass this to my ModelBinder, my ModelBinder would turn it into the IEnumerable.

I am using AutoFac. Is it possible that AutoFac is injecting an empty array into my controller method? I haven't had problems like this in other places (and we use AutoFac everywhere in this project.)


Edit2: I also tried decorating both the idArgs action parameter, and the controller with [ModelBinder(typeof(IEnumerableOfIntCSVModelBinder))], but this had no effect.


回答1:


I see that you have a JsonValueProviderFactory added in your Application_Start. Maybe there is something in the implementation of this factory that prevents the model binder from being hit?

Also the url you have shown /api/v1/widgets/1,2,3 has no relation to the route definition that you have "restapi/{controller}/{idArgs}".




回答2:


Could you try moving your route to be the first one registered? I just tried coding this up and had an issue where my route wasn't firing until I moved it's registration above the default route registration. Routes appear to be run in the order they are registered, so if you have a more specific registration after and more general registration, it may not fire.

In this example, the second route never gets called:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional });

routes.MapRoute(
    "Ids",
    "{controller}/{action}/{ids}",
    new { controller = "Home", action = "Index", ids = UrlParameter.Optional },
    new { ids = @"^(\d+,)+\d+,?$" });

But if you reverse their order, then "Ids" gets called.



来源:https://stackoverflow.com/questions/5519548/modelbinder-is-not-invoked

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!