Asp.Net MVC Beta:以前的 RouteData 会覆盖当前的 RouteData?

发布于 2024-07-07 06:23:14 字数 1210 浏览 6 评论 0原文

我有类似于以下方法:

    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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

二手情话 2024-07-14 06:23:14

我很难从你的帖子中说出你期望发生什么以及正在发生什么。 您的 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. :)

倾城°AllureLove 2024-07-14 06:23:14

问题是生活方式,我完全忽略了它被定义的事实,这意味着默认情况下控制器将使用单例生活方式。 将所有控制器的生活方式设置为瞬态将解决此问题。

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.

家住魔仙堡 2024-07-14 06:23:14

如果你使用spring.net修改
控制器的单例设置为“false”

if you use spring.net modify
Controller's singleton to "false"

诺曦 2024-07-14 06:23:14

在 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文