Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 3 关于IIS7的Spring.NET和MVC3-会话范围行为_Asp.net Mvc 3_Scope_Spring.net - Fatal编程技术网

Asp.net mvc 3 关于IIS7的Spring.NET和MVC3-会话范围行为

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

也许这是一个愚蠢的问题,我只是不明白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>
并使用

<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); }
        }  
    }