Spring.NET和MVC3上IIS7 - 会话范围的行为 [英] Spring.NET and MVC3 on IIS7 - session scope behaviour
问题描述
也许这是一个愚蠢的问题,我根本不知道如何Spring和IIS的工作,但让我们不妨一试。
probably it's a stupid question and I simply did not understand how Spring and IIS work, but lets give it a try.
我是相当新的ASP.NET和,据我了解,该会话处理类似的Apache / PHP:
I'm quite new to ASP.NET and as far as I understand, the session handling is similar to Apache/PHP:
的一个会话浏览器的选项卡之间共享,但是不同的浏览器之间没有。即如果我在Firefox打开我的网页,并把东西在车中,车仍然会包含我在另一个选项卡项目,但打开Internet Explorer中的非常相同的页面应该给我一个空的购物车。的
不过,我可以用Spring.NET无法重现此问题。
However I cannot reproduce this behaviour using Spring.NET.
我做了一个hello世界与它在会话范围指出一个购物车对象:
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>
如果我添加的东西到我的车,它坚持在任何选项卡和浏览器。因此,这在我看来,如果这个对象是IIS应用程序的运行过程中一个真正的单身人士,因此持续性。
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.
,你会说什么:为什么我使用属性单=真正的
在我的Spring配置?那么,如果我删除,或将其设置为假
,那么对象不会在会议上坚持,但在每次请求将被重新创建,从而失去它的数据。
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.
Spring.NET的文档未谈论在所有MVC上下文中的单
属性,我花了一些时间来弄清楚,它似乎使用要求MVC3。
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" />
或
<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.
我的猜测是,该会话实际未Firefox和IE浏览器之间共享,但车对象只是在应用范围,因为我使用的春天走错了路。
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.
谁能给我建议或暗示什么,我做错了,或这是IIS7的一个问题?
Can anyone give me advice or hints what I'm doing wrong or is this a problem in IIS7?
推荐答案
这是一个错误。
后spring.net源$ C $ C,我们发现了一些过度的调试:
After some excessive debugging of the spring.net source code we found out:
- 会话支持范围内的对象是由
spring.web
DLL给予 - 的
spring.web.mvc
DLL不依赖于spring.web
- 这意味着,这是不可能实例化一个
MvcApplicationContext
,可以解决会话范围内的对象
- Support for session scoped objects is given by the
spring.web
dll - The
spring.web.mvc
dll does not depend onspring.web
- This means, it is impossible to instantiate an
MvcApplicationContext
that can resolve session scoped objects
下面的解决方案显示了一个自定义的 MvcApplicationContext
,充分以便使用spring.net会话范围内MVC3对象。
The following solution shows a custom MvcApplicationContext
that fully enables session scoped objects within MVC3 using spring.net.
之所以一个标准的应用程序上下文无法解析的网络范围是,它的使用类 RootObjectDefinition
WHIS不知道关于范围
属性(在配置XML)。在的WebApplicationContext
,而不是实例化 RootWebObjectDefinition
类型,哪知道的范围。
The reason why a standard application context cannot resolve web scopes is that it's using the class RootObjectDefinition
whis doesn't know about the scope
attribute (in the config xml). The WebApplicationContext
instead instantiates RootWebObjectDefinition
types, which know the scope.
的 WebObjectsFactory
覆盖方法 CreateRootObjectDefinition
返回 RootWebObjectDefinition $ C的实例$ C>。这就是之一,我们希望从我们的应用程序上下文返回。这是通过覆盖方法
CreateObjectsFactory
完成的。
The WebObjectsFactory
overrides the method CreateRootObjectDefinition
which returns instances of RootWebObjectDefinition
. This is the one, we want to return from our application context. This is done by overriding the method CreateObjectsFactory
.
接下来的事情,我们必须覆盖的方法 CreateXmlObjectDefinitionReader
。当春乃发生读取从配置元数据,也不会像解析范围
附加属性,如果我们不采取特定的读者。因此,我们将使用 WebObjectDefinitionReader
在我们的应用程序上下文。
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 like scope
if we don't take a specific reader. Therefore we will use the WebObjectDefinitionReader
in our application context.
有关会话的配置范围内的对象,你可以离开了单
属性,或者明确地将其设置为真正
。否则值为假
会话范围将肯定被禁用。
For the configuration of your session scoped objects, you can either leave out the singleton
attribute or set it explicitly to true
. Otherwise with value false
the session scope will be disabled for sure.
例如:
<objects xmlns="http://www.springframework.net">
<object id="shoppingCart" type="ShoppingCart, ..." singleton="true" scope="session" />
</objects>
步骤分步解决方案:
- 创建
MvcWebApplicationContext
从MvcApplicationContext
继承。您将需要重写上面提到的两种方法,并创建默认的构造函数。 - 创建一个
MvcWebContextHandler
从MvcContextHandler
继承。这将触发我们的自定义应用程序上下文将被使用。 - 在
web.config中使用自定义上下文句柄
。 - 对于IIS6支持或Visual Studio内置的web服务器:添加
WebSupportModule
到的System.Web
部分 - 对于IIS7支持。添加
WebSupportModule
到system.webserver
部分
- Create
MvcWebApplicationContext
inheriting fromMvcApplicationContext
. You will need to override the two methods mentioned above and create default constructors. - Create a
MvcWebContextHandler
inheriting fromMvcContextHandler
. This will trigger that our custom application context will be used. - Use custom context handler in your
web.config
. - For IIS6 support or visual studio build-in webserver: add
WebSupportModule
tosystem.web
section. - For IIS7 support: Add
WebSupportModule
tosystem.webserver
section.
web.config中:
web.config:
<configSections>
<sectionGroup name="spring">
<section name="context" type="YourNamspace.MvcWebContextHandler, YourAssembly"/>
....
</sectionGroup>
....
</configSections>
<!-- IIS6 -->
<system.web>
<httpModules>
<add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
</httpModules>
</system.web>
<!-- IIS7 -->
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true" >
<add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
</modules>
</system.webServer>
自定义应用程序上下文类:
Custom application context class:
public class MvcWebApplicationContext: MvcApplicationContext {
public MvcWebApplicationContext(string name, bool caseSensitive, params string[] configurationLocations)
: this(new MvcApplicationContextArgs(name, null, configurationLocations, null, caseSensitive))
{ }
public MvcWebApplicationContext(string name, bool caseSensitive, IApplicationContext parentContext, params string[] configurationLocations)
: this(new MvcApplicationContextArgs(name, parentContext, configurationLocations, null, caseSensitive))
{ }
public MvcWebApplicationContext(MvcApplicationContextArgs args)
: base(args)
{ }
public MvcWebApplicationContext(string name, bool caseSensitive, string[] configurationLocations, IResource[] configurationResources)
: this(new MvcApplicationContextArgs(name, null, configurationLocations, configurationResources, caseSensitive))
{ }
public MvcWebApplicationContext(params string[] configurationLocations)
: this(new MvcApplicationContextArgs(string.Empty, null, configurationLocations, null, false))
{ }
protected override XmlObjectDefinitionReader CreateXmlObjectDefinitionReader(DefaultListableObjectFactory objectFactory)
{
return new WebObjectDefinitionReader(GetContextPathWithTrailingSlash(), objectFactory, new XmlUrlResolver());
}
protected override DefaultListableObjectFactory CreateObjectFactory()
{
return new WebObjectFactory(GetContextPathWithTrailingSlash(), IsCaseSensitive);
}
private string GetContextPathWithTrailingSlash()
{
string contextPath = this.Name;
if (contextPath == DefaultRootContextName)
{
contextPath = "/";
}
else
{
contextPath = contextPath + "/";
}
return contextPath;
}
}
自定义背景下处理类:
Custom context handler class:
public class MvcWebContextHandler : MvcContextHandler {
protected override Type DefaultApplicationContextType
{
get { return typeof(MvcWebApplicationContext); }
}
}
我们加入这个bug到Spring.NET的问题跟踪:
https://jira.springsource.org/browse/SPRNET-1450
We added this bug to Spring.NET's issue tracker: https://jira.springsource.org/browse/SPRNET-1450
这篇关于Spring.NET和MVC3上IIS7 - 会话范围的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!