ModelBinder没有被调用
根据我之前的问题,我实现了一个映射/api/v1/widgets/1,2,3
到
// WidgetsController.cs:
public ActionResult Show(IEnumerable<int> idArgs)
{
}
这已经工作了一段时间,但现在不再工作了。 我的 ModelBinder 甚至根本没有被调用。当我的操作被调用时,idArgs
的值是空列表,即使我将其默认值设置为 null
在路由中,这表明默认模型绑定器认为它从某个地方获取值。自上周工作以来我所做的唯一更改是,之前我将操作称为 ShowMany
。从那时起,我将其重命名为 Show
。谁能帮我弄清楚为什么我的 ModelBinder 没有被调用?
在 global.asax.cs 中,我有
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
ModelBinders.Binders.Add(typeof(IEnumerable<int>), new IEnumerableOfIntCSVModelBinder());
}
路线看起来像这样(我已经验证了该路线正在使用):
context.MapRoute(
"show",
"api/{controller}/{idArgs}",
new { action = "show" },
new { httpMethod = new HttpMethodConstraint("GET"), idArgs = @"^(\d+,)+\d+,?$" }
);
编辑:我也尝试过更多地弄乱路线当注释掉 JsonValueProvider
时,我仍然得到一个空数组。在我的控制器中,我可以
var ids = RouteData.Values["idArgs"];
获取字符串“1,2,3”。如果框架将其传递给我的 ModelBinder,我的 ModelBinder 会将其转换为 IEnumerable
。
我正在使用 AutoFac。 AutoFac 是否有可能将空数组注入到我的控制器方法中?我在其他地方没有遇到过这样的问题(我们在这个项目中到处都使用 AutoFac。)
Edit2:我还尝试装饰 idArgs
操作参数和控制器与 [ModelBinder(typeof(IEnumerableOfIntCSVModelBinder))]
,但这没有效果。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我看到您在
Application_Start
中添加了一个JsonValueProviderFactory
。也许这个工厂的实现中有一些东西可以防止模型绑定器被击中?此外,您显示的网址
/api/v1/widgets/1,2,3
与您的路由定义没有关系"restapi/{controller}/{idArgs}"< /代码>。
I see that you have a
JsonValueProviderFactory
added in yourApplication_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}"
.您可以尝试将您的路线移至第一个注册的路线吗?我只是尝试对此进行编码,但遇到了一个问题,即我的路线没有触发,直到我将其注册移至默认路线注册之上。路由似乎按照注册的顺序运行,因此如果您在注册之后进行了更具体的注册,并且在更一般的注册之后进行了更具体的注册,则它可能不会触发。
在此示例中,第二条路由永远不会被调用:
但是如果颠倒它们的顺序,则会调用“Ids”。
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:
But if you reverse their order, then "Ids" gets called.