Spring.NET和MVC3上IIS7 - 会话范围的行为 [英] Spring.NET and MVC3 on IIS7 - session scope behaviour

查看:121
本文介绍了Spring.NET和MVC3上IIS7 - 会话范围的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

也许这是一个愚蠢的问题,我根本不知道如何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:


  1. 会话支持范围内的对象是由 spring.web DLL给予

  2. spring.web.mvc DLL不依赖于 spring.web

  3. 这意味着,这是不可能实例化一个 MvcApplicationContext ,可以解决会话范围内的对象

  1. Support for session scoped objects is given by the spring.web dll
  2. The spring.web.mvc dll does not depend on spring.web
  3. 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 。这就是之一,我们希望从我们的应用程序上下文返回。这是通过覆盖方法 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>

步骤分步解决方案:


  1. 创建 MvcWebApplicationContext MvcApplicationContext 继承。您将需要重写上面提到的两种方法,并创建默认的构造函数。

  2. 创建一个 MvcWebContextHandler MvcContextHandler 继承。这将触发我们的自定义应用程序上下文将被使用。

  3. web.config中使用自定义上下文句柄

  4. 对于IIS6支持或Visual Studio内置的web服务器:添加 WebSupportModule 的System.Web 部分

  5. 对于IIS7支持。添加 WebSupportModule system.webserver 部分

  1. Create MvcWebApplicationContext inheriting from MvcApplicationContext. You will need to override the two methods mentioned above and create default constructors.
  2. Create a MvcWebContextHandler inheriting from MvcContextHandler. This will trigger that our custom application context will be used.
  3. Use custom context handler in your web.config.
  4. For IIS6 support or visual studio build-in webserver: add WebSupportModule to system.web section.
  5. For IIS7 support: Add WebSupportModule to system.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆