当前位置:  开发笔记 > 编程语言 > 正文

如何在ServiceStack服务实现中使用标准ASP.NET会话对象

如何解决《如何在ServiceStack服务实现中使用标准ASP.NET会话对象》经验,为你挑选了2个好方法。

我刚刚开始使用ServiceStack,作为测试用例,我希望重新编写使用标准ASP.Net处理程序构建的现有服务.我已经成功地将它全部工作,因为我想要它,但有某些方面利用ASP.Net Session对象.

我已经尝试将IRequiresSessionState添加到服务接口中:

public class SessionTestService : RestServiceBase, IRequiresSessionState {
    public override object OnPost(SessionTest request) {
        // Here I want to use System.Web.HttpContext.Current.Session
    }
}

问题是我似乎无法使其工作,因为Session对象始终为null.

我做了很多谷歌搜索,并对https://github.com/mythz/ServiceStack/blob/master/tests/ServiceStack.WebHost.IntegrationTests/Services/Secure.cs和类似问题感到困惑,但我找不到任何执行此操作的示例代码(令我感到惊讶).任何人都可以解释为什么以上不起作用,并建议我需要做什么才能使它工作?

注意:最终我可能希望用Redis替换它或者尝试删除任何服务器端会话要求,但我认为我暂时使用ASP.Net实现,以使工作正常并避免重新处理它在这一点上超过必要的.



1> mythz..:

使用ServiceStack ISession

ServiceStack有一个新的ISession界面支持,ICacheClient它允许您ISession在MVC控制器,ASP.NET基页和ServiceStack的Web服务之间共享相同的Cookie,这些Web服务共享相同的Cookie ID,允许您在这些Web框架之间自由共享数据.

注意:ISession是一个干净的实现,它完全绕过现有的ASP.NET会话和ServiceStack自己的组件,如ServiceStack的MVC PowerPack中所述,并在Sessions wiki页面中详细解释.

要轻松使用ServiceStack的Session(Cache和JSON Serializer),您的控制器将继承自ServiceStackController(在MVC中)或PageBase(在ASP.NET中)

ServiceStack中还添加了新的身份验证/验证功能,您可以在Wiki上阅读:

身份验证和授权

验证

使用ASP.NET Session

本质上,ServiceStack只是一组在ASP.NET或HttpListener主机运行的轻量级IHttpHandler.如果托管在IIS/ASP.NET(最常见)中,它就像普通的ASP.NET请求一样工作.

ServiceStack中的任何内容都不会访问或影响底层ASP.NET应用程序中已配置的缓存和会话提供程序.如果要启用它,则需要在ASP.NET中正常配置它(即在ServiceStack之外),请参阅:

http://msdn.microsoft.com/en-us/library/ms178581.aspx

配置完成后,您可以通过单例访问ServiceStack Web服务中的ASP.NET会话:

HttpContext.Current.Session

或者通过底层的ASP.NET HttpRequest:

var req = (HttpRequest)base.RequestContext.Get().OriginalRequest;
var session = req.RequestContext.HttpContext.Session;

虽然由于强制依赖XML配置并且默认情况下性能下降,但我更倾向于避免使用ASP.NET的Session,而是选择使用ServiceStack附带的更清晰的Cache Clients.

基本上,Sessions的工作方式(包括ASP.NET)是一个包含唯一ID的cookie,它被添加到唯一标识浏览器会话的Response中.此id指向服务器上匹配的Dictionary/Collection,表示浏览器的Session.

您链接到的IRequiresSession接口默认情况下不执行任何操作,它只是向自定义请求筛选器或基本Web服务发出信号通知此请求需要进行身份验证的方式(即,您应该放置验证/身份验证逻辑的两个位置)在ServiceStack中).

这是一个Basic Auth实现,它查看Web服务是否安全,如果是,请确保它们已经过身份验证.

这是另一个身份验证实现,它将验证标记有[Authenticate]属性的所有服务,以及如何通过在Request DTO上添加Attribute 来为您的服务启用身份验证.

ServiceStack中的新身份验证模型

上述实现是ServiceStack下一版本中包含的多身份验证提供程序模型的一部分.以下是显示如何在应用程序中注册和配置新Auth模型的参考示例.

认证策略

新的Auth模型完全是一种选择性的便利,因为您可以不使用它并使用请求过滤器基类(通过重写OnBeforeExecute)实现类似的行为.事实上,新的Auth服务实际上并没有内置到ServiceStack中.整个实现位于可选的ServiceStack.ServiceInterfaces项目中,并使用自定义请求筛选器实现.

以下是我多年来使用的不同身份验证策略:

标记需要使用[Attribute]进行身份验证的服务.可能是最惯用的C#方式,非常适合通过Cookie传递session-id.

特别是在Web上下文之外,有时使用更明确的IRequiresAuthentication接口更好,因为它提供对身份验证所需的User和SessionId的强类型访问.

您可以在每个需要它的服务上使用1-liner进行身份验证 - 在特定的基础上.当您很少需要身份验证的服务时,这是一种合适的方法



2> Richard Fawc..:

这是@mythz的一个伟大而全面的答案.但是,当尝试通过HttpContext.Current.SessionServiceStack Web服务访问ASP.NET会话时,它总是返回null给我.这是因为ServiceStack中的HttpHandler都没有用IRequiresSessionState接口装饰,因此.NET Framework不向我们提供会话对象.

为了解决这个问题,我实现了两个新类,它们都使用装饰器模式为我们提供了所需的东西.

首先,新的IHttpHandler需要会话状态.它包装了IHttpHandlerServiceStack提供的并将调用传递给它...

public class SessionHandlerDecorator : IHttpHandler, IRequiresSessionState {
    private IHttpHandler Handler { get; set; }

    internal SessionHandlerDecorator(IHttpHandler handler) {
        this.Handler = handler;
    }

    public bool IsReusable {
        get { return Handler.IsReusable; }
    }

    public void ProcessRequest(HttpContext context) {
        Handler.ProcessRequest(context);
    }
}

接下来,在将返回的处理程序包装到新的... 之前,一个新的IHttpHandlerFactory委托生成IHttpHandlerServiceStack 的职责SessionHandlerDecorator.

public class SessionHttpHandlerFactory : IHttpHandlerFactory {
    private readonly static ServiceStackHttpHandlerFactory factory = new ServiceStackHttpHandlerFactory();

    public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated) {
        var handler = factory.GetHandler(context, requestType, url, pathTranslated);
        return handler == null ? null : new SessionHandlerDecorator(handler);
    }

    public void ReleaseHandler(IHttpHandler handler) {
        factory.ReleaseHandler(handler);
    }

}

然后,只需将typeWeb.config中处理程序中的属性更改为SessionHttpHandlerFactory而不是ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack,您的Web服务现在应该具有可用于它们的ASP.NET会话.

尽管如此,我完全赞同ISessionServiceStack提供的新实现.但是,在某些情况下,在成熟的产品上,用新的实现替换ASP.NET会话的所有用途似乎太大了,因此这种解决方法!

推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有