IIS7 上的 Spring.NET 和 MVC3 - 会话范围行为
可能这是一个愚蠢的问题,我根本不明白 Spring 和 IIS 是如何工作的,但让我们尝试一下。
我对 ASP.NET 很陌生,据我所知,会话处理类似于 Apache/PHP:
会话在浏览器的选项卡之间共享,但不在不同的浏览器之间共享。即,如果我在 Firefox 中打开页面并将某些东西放入购物车,购物车仍将在另一个选项卡中包含我的商品,但在 Internet Explorer 中打开同一页面应该会显示一个空购物车。
但是我无法重现这种行为使用 Spring.NET。
我用购物车对象创建了一个 hello-world,该对象在会话范围中注明:
<objects xmlns="http://www.springframework.net">
<object id="shoppingCart" type="DemoShop.Models.Cart.ShoppingCart, DemoShop" singleton="true" scope="session" />
</objects>
如果我将某些东西添加到购物车中,它会在任何选项卡和浏览器中持续存在。所以在我看来,这个对象好像是一个真正的单例,因此在 IIS 应用程序运行时是持久的。
我知道,你会说:为什么我在 spring 配置中使用属性 singleton="true"
?如果我删除它或将其设置为 false,那么该对象将不会保留在会话中,而是会在每个请求时重新创建,从而丢失其数据。
Spring.NET 文档根本没有谈论 MVC 上下文中的 singleton
属性,我花了一些时间才弄清楚,使用 MVC3 似乎需要它。
我能够使用
<object id="..." type="..., ..." singleton="true" scope="application" />
使用请求范围对象
<object id="..." type="..., ..." scope="request" />
或
<object id="..." type="..., ..." singleton="false" scope="request" />
成功创建应用程序范围对象但是,将 singleton
属性排除在外,始终将我的对象放入请求范围中,无论我在 中实际注意到哪个范围范围
属性。
我的猜测是,该会话实际上并未在 Firefox 和 IE 之间共享,但购物车对象只是在应用程序范围内,因为我使用 spring 的方式错误。
任何人都可以给我建议或提示我做错了什么或者这是 IIS7 中的问题吗?
probably it's a stupid question and I simply did not understand how Spring and IIS work, but lets give it a try.
I'm quite new to ASP.NET and as far as I understand, the session handling is similar to Apache/PHP:
A session is shared between tabs of a browser, but not between different browsers. I.e. if I open my page in Firefox and put something in the cart, the cart will still contain my items in another tab, but opening the very same page in Internet Explorer should show me an empty cart.
However I cannot reproduce this behaviour using Spring.NET.
I made a hello-world with a shopping cart object which is noted in session scope:
<objects xmlns="http://www.springframework.net">
<object id="shoppingCart" type="DemoShop.Models.Cart.ShoppingCart, DemoShop" singleton="true" scope="session" />
</objects>
If I add something into my cart, it persists across any tab and browser. So this looks to me as if this object is a real singleton and thus persistent during the runtime of the IIS application.
I know, what you are going to say: Why did I use the attribute singleton="true"
in my spring config? Well if I remove it or set it to false
, then the object will not persist in the session, but will be re-created on every request and thus lose it's data.
The Spring.NET documentation is not speaking about the singleton
attribute in MVC context at all and it took me some time to figure out, that it seem to be required using MVC3.
I was able to successfully create application scope objects using
<object id="..." type="..., ..." singleton="true" scope="application" />
and request scope object using either
<object id="..." type="..., ..." scope="request" />
or
<object id="..." type="..., ..." singleton="false" scope="request" />
However leaving the singleton
attribute out, always put my object in request scope no matter which scope I actually noted in the scope
attribute.
My guess is, that the session is not actually shared between Firefox and IE, but the cart object is simply in application scope, because I'm using spring the wrong way.
Can anyone give me advice or hints what I'm doing wrong or is this a problem in IIS7?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是一个错误。
对 spring.net 源代码进行一些过度调试后,我们发现:
spring.web
MvcApplicationContext
以下解决方案显示了自定义
MvcApplicationContext
完全启用会话范围内的对象MVC3 使用 spring.net。标准应用程序上下文无法解析 Web 范围的原因是它使用的类
RootObjectDefinition
不知道scope
属性(在配置 xml 中)。WebApplicationContext
相反,实例化RootWebObjectDefinition
类型,它知道范围。WebObjectsFactory
重写了CreateRootObjectDefinition
方法,该方法返回RootWebObjectDefinition
的实例。这就是我们想要从应用程序上下文中返回的内容。这是通过重写方法CreateObjectsFactory
来完成的。接下来,我们必须重写方法
CreateXmlObjectDefinitionReader
。当 spring 从配置中读取元数据时,如果我们不使用特定的读取器,它不会解析诸如scope
之类的附加属性。因此,我们将在应用程序上下文中使用WebObjectDefinitionReader
。对于会话范围对象的配置,您可以省略
singleton
属性或将其显式设置为true
。否则,如果值为 false,会话范围肯定会被禁用。示例:
分步解决方案:
MvcApplicationContext
的MvcWebApplicationContext
。您将需要重写上面提到的两个方法并创建默认构造函数。MvcContextHandler
的MvcWebContextHandler
。这将触发我们的自定义应用程序上下文将被使用。web.config
中使用自定义上下文处理程序。WebSupportModule
添加到system.web
部分。WebSupportModule
添加到system.webserver
部分。web.config:
自定义应用程序上下文类:
自定义上下文处理程序类:
我们将此错误添加到 Spring.NET 的问题跟踪器中:
https://jira.springsource.org/browse/SPRNET-1450
It's a bug.
After some excessive debugging of the spring.net source code we found out:
spring.web
dllspring.web.mvc
dll does not depend onspring.web
MvcApplicationContext
that can resolve session scoped objectsThe following solution shows a custom
MvcApplicationContext
that fully enables session scoped objects within MVC3 using spring.net.The reason why a standard application context cannot resolve web scopes is that it's using the class
RootObjectDefinition
whis doesn't know about thescope
attribute (in the config xml). TheWebApplicationContext
instead instantiatesRootWebObjectDefinition
types, which know the scope.The
WebObjectsFactory
overrides the methodCreateRootObjectDefinition
which returns instances ofRootWebObjectDefinition
. This is the one, we want to return from our application context. This is done by overriding the methodCreateObjectsFactory
.Next thing, we have to override is the method
CreateXmlObjectDefinitionReader
. When spring is reading the metadata from the config, it will not parse additional attributes likescope
if we don't take a specific reader. Therefore we will use theWebObjectDefinitionReader
in our application context.For the configuration of your session scoped objects, you can either leave out the
singleton
attribute or set it explicitly totrue
. Otherwise with valuefalse
the session scope will be disabled for sure.EXAMPLE:
Step-by-Step solution:
MvcWebApplicationContext
inheriting fromMvcApplicationContext
. You will need to override the two methods mentioned above and create default constructors.MvcWebContextHandler
inheriting fromMvcContextHandler
. This will trigger that our custom application context will be used.web.config
.WebSupportModule
tosystem.web
section.WebSupportModule
tosystem.webserver
section.web.config:
Custom application context class:
Custom context handler class:
We added this bug to Spring.NET's issue tracker:
https://jira.springsource.org/browse/SPRNET-1450