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?
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