Asp.Net MVC Beta:以前的 RouteData 会覆盖当前的 RouteData?
我有类似于以下方法:
public ActionResult Details(int id)
{
var viewData = new DetailsViewData
{
Booth = BoothRepository.Find(id),
Category = ItemType.HotBuy
};
return View(viewData);
}
和以下路线:
routes.MapRoute("shows","shows/{controller}/{action}/{id}", new {id = 0});
在 Beta 之前,当我有预览版 3 时,一切正常。现在,该方法将在我第一次执行操作时正确填充 id。 然而,第二次控制器的 ModelState
包含上次使用的 id 值。 这会导致 ActionInvoker
在方法的参数中使用它,而不是 Route
值。
因此,如果我对两个不同的实体调用该操作两次,结果如下:
www.mysite.com/shows/Booth/Details/1 => Details(1)
www.mysite.com/shows/Booth/Details/2 => Details(1) //from ModelState["id"]
从我使用 Reflector 的快速扫描来看,它似乎首先将参数绑定到 ModelState,然后绑定到路由。 然而,我什至从未发布过该模型的任何内容。 据我所知 ModelState 不应包含任何内容。
这是 Beta 版中的错误,可能是我代码中某个地方的错误,还是有一些我不知道的设计功能? 任何对 ModelState 的本质以及为什么会发生这种情况的见解都会受到赞赏。
编辑: 我发现,如果您从在 Asp.Net 应用程序的生命周期中存在的 IoC 容器实例化控制器,则此问题实际上是 DefaultValueProvider 似乎存在错误的症状。发生的情况是 DefaultValueProvider 使用第一个 ControllerContext提供给控制器并且在重新创建控制器之前永远不会更新它。 这会导致旧的 RouteData 而不是当前的 RouteData 用于方法参数。
I have something similar to the following method:
public ActionResult Details(int id)
{
var viewData = new DetailsViewData
{
Booth = BoothRepository.Find(id),
Category = ItemType.HotBuy
};
return View(viewData);
}
and the following Route:
routes.MapRoute("shows","shows/{controller}/{action}/{id}", new {id = 0});
Everything worked fine before the Beta, when I had Preview 3. Now the method will fill the id correctly the first time I execute the action. However the second time the controller's ModelState
contains the last-use id value. This causes the ActionInvoker
to use it in the method's parameter instead of the Route
value.
So if I call the action twice on two different entities the results are such:
www.mysite.com/shows/Booth/Details/1 => Details(1)
www.mysite.com/shows/Booth/Details/2 => Details(1) //from ModelState["id"]
From my quick scan with Reflector it seems it first binds parameters to the ModelState then to Routes. However, I never even posted anything from the model. As far as I can tell the ModelState should not contain anything.
Is this a bug in the Beta, possibly a bug somewhere in my code, or is there some design feature that I am ignorant of? Any insight into the nature of ModelState and why this happens is appreciated.
EDIT:
I discovered that this issue is actually a symptom of what appears to be a bug with the DefaultValueProvider if you instantiate a Controller from an IoC container that exists for the lifetime of the Asp.Net application.What happens is that the DefaultValueProvider uses the first ControllerContext given to the Controller and never updates it until the controller is recreated. This causes old RouteData to be used for method parameters instead of the current RouteData.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我很难从你的帖子中说出你期望发生什么以及正在发生什么。 您的 BoothRepository.Find 方法是否可能存在错误,导致每次都返回相同的内容?
ModelBinder 不应该影响此方法,因为操作方法的参数是简单类型 int。
这两个请求都是 GET 请求吗? 如果您仍然遇到问题,您可以尝试创建最简单的重现并将其通过电子邮件发送到 philha - microsoft dot com 吗?
编辑:问题最终是开发人员试图跨请求重用 valueprovider(通过让 Castle Windsor 管理控制器的生命周期)。 目前,不支持跨请求重用控制器实例,就像使用具有 IsReusable 属性的 IHttpHandler 一样。 因此,一般来说,跨请求重用控制器需要您做更多的工作。 :)
It's hard for me to tell what you expect to happen and what is happening from your post. Is it possible there's an error in your BoothRepository.Find method such that it returns the same thing every time?
ModelBinder should not be affecting this method because the parameter to the action method is a simple type, int.
Were both of these requests GET requests? If you still are having problems, can you try and create the simplest repro possible and email it to philha - microsoft dot com?
EDIT: The problem ended up being that the developer was attempting to re-use the valueprovider across requests (by having Castle Windsor manage the lifecycle of Controllers). Right now, there's no support for re-using controller instances across requests like you would with IHttpHandler which has a IsReusable property. So in general, reusing controllers across requests requires doing a lot more work on your end. :)
问题是生活方式,我完全忽略了它被定义的事实,这意味着默认情况下控制器将使用单例生活方式。 将所有控制器的生活方式设置为瞬态将解决此问题。
The problem is the LifeStyle, I completetly overlooked the fact it was being defined, which means by default the controllers will use the Singleton lifestyle. Setting the LifeStyle to Transient for all controllers will sort this problem.
如果你使用spring.net修改
控制器的单例设置为“false”
if you use spring.net modify
Controller's singleton to "false"
在 Spring.NET 或 Windsor 等 IoC 容器中使用 Singleton 行为时,这是一个常见问题。 控制器不应该有单例行为,因为 ControllerContext 是针对每个请求的,很像 HttpContext。
This is a common issue when using Singleton behavior with a IoC container such as Spring.NET or Windsor. Controllers should not have singleton behavior because the ControllerContext is per request, much like HttpContext.