Asp.net mvc 3 关于IIS7的Spring.NET和MVC3-会话范围行为
也许这是一个愚蠢的问题,我只是不明白Spring和IIS是如何工作的,但让我们来试试 我对ASP.NET非常陌生,据我所知,会话处理类似于Apache/PHP: 会话在浏览器的选项卡之间共享,但不在不同浏览器之间共享。也就是说,如果我在Firefox中打开我的页面并在购物车中放置了一些东西,购物车仍将在另一个选项卡中包含我的项目,但在Internet Explorer中打开同一页面时,应该会显示一个空购物车 但是,我无法使用Spring.NET重现这种行为 我用一个购物车对象创建了一个hello world,该对象在会话范围中注明:Asp.net mvc 3 关于IIS7的Spring.NET和MVC3-会话范围行为,asp.net-mvc-3,scope,spring.net,Asp.net Mvc 3,Scope,Spring.net,也许这是一个愚蠢的问题,我只是不明白Spring和IIS是如何工作的,但让我们来试试 我对ASP.NET非常陌生,据我所知,会话处理类似于Apache/PHP: 会话在浏览器的选项卡之间共享,但不在不同浏览器之间共享。也就是说,如果我在Firefox中打开我的页面并在购物车中放置了一些东西,购物车仍将在另一个选项卡中包含我的项目,但在Internet Explorer中打开同一页面时,应该会显示一个空购物车 但是,我无法使用Spring.NET重现这种行为 我用一个购物车对象创建了一个hello
<objects xmlns="http://www.springframework.net">
<object id="shoppingCart" type="DemoShop.Models.Cart.ShoppingCart, DemoShop" singleton="true" scope="session" />
</objects>
并使用
<object id="..." type="..., ..." scope="request" />
或
但是,将singleton
属性保留在外面,不管我在scope
属性中实际注意到哪个范围,总是将我的对象放在请求范围中
我的猜测是,会话实际上并没有在Firefox和IE之间共享,但cart对象只是在应用程序范围内,因为我使用spring的方式不对
谁能给我一些建议或提示我做错了什么,或者这是IIS7中的一个问题吗?这是一个bug
在对spring.net源代码进行过多调试后,我们发现:
spring.web
dll提供了对会话范围对象的支持spring.web.mvc
dll不依赖于spring.web
mvcapApplicationContext
MVCAPApplicationContext
,它使用spring.net在MVC3中完全启用会话范围的对象
标准应用程序上下文无法解析web作用域的原因是它使用了类RootObjectDefinition
,而它不知道scope
属性(在配置xml中)。相反,WebApplicationContext
实例化了RootWebObjectDefinition
类型,这些类型知道范围
WebObjectsFactory
覆盖方法CreateRootObjectDefinition
,该方法返回RootWebObjectDefinition
的实例。这就是我们希望从应用程序上下文返回的内容。这是通过重写方法CreateObjectsFactory
实现的
接下来,我们必须重写方法CreateXmlObjectDefinitionReader
。当spring从配置中读取元数据时,如果我们不使用特定的读取器,它将不会解析额外的属性,如scope
。因此,我们将在应用程序上下文中使用WebObjectDefinitionReader
对于会话范围对象的配置,您可以省略singleton
属性,或者将其显式设置为true
。否则,如果值为false
,则会话范围肯定会被禁用
例如:
<objects xmlns="http://www.springframework.net">
<object id="shoppingCart" type="ShoppingCart, ..." singleton="true" scope="session" />
</objects>
自定义应用程序上下文类:
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;
}
}
自定义上下文处理程序类:
public class MvcWebContextHandler : MvcContextHandler {
protected override Type DefaultApplicationContextType
{
get { return typeof(MvcWebApplicationContext); }
}
}
我们将此错误添加到Spring.NET的问题跟踪程序中:
您解决了这个问题吗?根据asp.net mvc和spring.net中的说明,它肯定应该是
。可能是您使用
禁用了会话状态吗?我已经阅读了文档,完全同意您的说法。尽管如此,只要我省略了singleton
属性,实例化对象总是在请求范围内。如果我没有显式地将singleton
设置为true
,无论scope
属性如何,我甚至无法获取应用程序范围对象。这就是为什么我如此好奇。但是我还没有解决它。我将创建一个简单的MVC2 hello world应用程序来检查它是否如文档所述。我还将检查会话状态模式。当然,我会在这里发布任何进展。非常感谢。我从ASP.NET将Spring.NET实现到默认的MVC2应用程序中,并复制了非常相同的行为:scope
属性被忽略,singleton
属性创建应用程序范围对象或请求范围对象。所以问题一定是我。这是Spring.net的issuetracker上的错误:是的,对不起,我忘记发布了。我把jira的链接添加到了答题帖上。谢谢你指出这一点;很高兴看到您找到了修复/解决方法。在Spring问题跟踪器上,我读到这个bug已经被确认,并且在asp.net mvc 3的Spring.net 1.3.2中得到了修复。但是,1.3.1/asp.net mvc 2还没有修复程序。但正如您所看到的,解决方法非常简单。只需在两个类中重写两个方法,就完成了。也可以直接在spring.net源代码中完成并重新编译。
<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>
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;
}
}
public class MvcWebContextHandler : MvcContextHandler {
protected override Type DefaultApplicationContextType
{
get { return typeof(MvcWebApplicationContext); }
}
}