ModelBinder is not called

Per my previous question , I applied a model binder that displays /api/v1/widgets/1,2,3 in

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

This worked for a while, but now it is no longer so. My ModelBinder is not even called at all. When my action is called, idArgs has the value of an empty list, even if I set its default value to null in the route, which suggests me that the default connecting device thinks it is getting some kind of value. The only change I made from last week when it was working is that I previously called my ShowMany. action ShowMany. . Since then I renamed it Show . Can someone help me understand why my ModelBinder is not being called?

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 checked that this route is used):

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

Edit: I already tried messing messing with routes, as well as commenting on JsonValueProvider , and I still get an empty array. In my controller I can do

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

and get the string "1,2,3". If only the infrastructure passes this to my ModelBinder, my ModelBinder will turn it into IEnumerable .

I am using AutoFac. Is it possible that AutoFac injects an empty array into my controller method? I had no such problems elsewhere (and we use AutoFac everywhere in this project.)


Edit2 . I also tried to decorate both the idArgs action parameter and the controller with [ModelBinder(typeof(IEnumerableOfIntCSVModelBinder))] , but this did not affect.

+3
source share
2 answers

I see that JsonValueProviderFactory added to Application_Start . Maybe there is something in the implementation of this factory that prevents the binder from getting onto the model?

Also, the pointer you specified /api/v1/widgets/1,2,3 has nothing to do with the route definition that you have "restapi/{controller}/{idArgs}" .

+1
source

Could you transfer your route first registered? I was just trying to code this and had a problem when my route didn't shoot until I moved it to register above the default route registration. Routes apparently start in the order in which they are registered, so if you have a more specific registration after a more general registration, it may not work.

In this example, the second route is never 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 cancel the order, then "Ids" is called.

0
source

All Articles