首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在ServiceStack服务实现中使用标准ASP.NET会话对象

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

Stack Overflow用户
提问于 2011-12-01 18:11:25
回答 4查看 6.7K关注 0票数 16

我刚刚开始使用ServiceStack,作为测试用例,我希望修改使用标准ASP.Net处理程序构建的现有服务。我已经设法让它按我想要的方式工作,但有一些方面利用了ASP.Net会话对象。

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

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

问题是我似乎不能让它工作,因为会话对象总是空的。

我做了很多谷歌搜索,对https://github.com/mythz/ServiceStack/blob/master/tests/ServiceStack.WebHost.IntegrationTests/Services/Secure.cs和类似的东西感到困惑,但我找不到任何示例代码来做这件事(这让我很惊讶)。有没有人能解释一下为什么上面的方法不起作用,并建议我需要做些什么才能使其正常工作?

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-12-05 10:10:12

使用ServiceStack ISession的

ServiceStack有一个由ICacheClient支持的新的ISession接口,它允许你在ISession控制器、ASP.NET基本页面和ServiceStack的Web服务之间共享相同的Cookie Id,从而允许你在这些web框架之间自由共享数据。

注意: ISession是一个干净的实现,它完全绕过了与ServiceStack自己的组件的现有ASP.NET会话,如ServiceStack's MVC PowerPack中所述,并在Sessions wiki page中进行了详细解释。

为了方便地使用ServiceStack的会话(缓存和JSON序列化器),让您的控制器继承自ServiceStackController (在MVC中)或PageBase (在ASP.NET中)

在ServiceStack中还添加了新的身份验证/验证功能,您可以在维基上了解到:

使用ASP.NET Session

本质上,ServiceStack只是一组运行在ASP.NET或HttpListener主机上的轻量级IHttpHandler's。如果托管在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<IHttpRequest>().OriginalRequest;
var session = req.RequestContext.HttpContext.Session;

尽管由于对XML config和degraded performance by default的强制依赖,我更倾向于避免使用ASP.Net的会话,而是选择使用ServiceStack中包含的更干净的Cache Clients

基本上,会话的工作方式(包括ASP.NET)是一个包含惟一id的cookie,被添加到唯一标识浏览器会话的响应中。此id指向表示浏览器会话的服务器上的匹配字典/集合。

默认情况下,您链接到的IRequiresSession接口不会做任何事情,它只是向自定义请求过滤器或基础web服务发出信号通知此请求需要进行身份验证(即,您应该在ServiceStack中放置验证/身份验证逻辑的两个位置)。

这里有一个Basic Auth implementation,用于查看web服务是否安全,如果是,请确保它们已通过身份验证。

下面是验证用Authenticate属性标记的所有服务的another authentication implementation,以及通过在请求DTO上添加该属性来验证how to enable Authentication for your service的示例。

ServiceStack中一种新的认证模型

上面的实现是下一版本ServiceStack中包含的多身份验证提供程序模型的一部分。下面的the reference example展示了如何在应用程序中注册和配置新的身份验证模型。

身份验证策略

新的身份验证模型完全是一种选择加入的便利,因为你可以不使用它,而是自己使用请求过滤器或在基类中实现类似的行为(通过覆盖OnBeforeExecute)。事实上,新的身份验证服务实际上并没有内置到ServiceStack本身中。整个实现位于可选的ServiceStack.ServiceInterfaces project中,并使用自定义请求过滤器实现。

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

  • 使用Attribute标记需要身份验证的服务。这可能是最常用的会话方式,当通过Cookie.
  • Especially将会话id传递到C#上下文之外时,有时使用更显式的IRequiresAuthentication接口会更好,因为它为用户提供了强类型的访问,Authentication.
  • You所需的SessionId可以只使用1行代码在需要它的每个服务上进行身份验证-在特定的基础上。当只有很少的服务需要authentication.

时,一种合适的方法

票数 28
EN

Stack Overflow用户

发布于 2012-02-08 21:00:04

这是@mythz给出的一个很好且全面的答案。但是,当尝试在ServiceStack web服务中通过HttpContext.Current.Session访问ASP.NET会话时,它总是为我返回null。这是因为ServiceStack中的HttpHandlers都没有使用IRequiresSessionState接口进行修饰,所以.NET框架没有为我们提供会话对象。

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

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

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,它将生成IHttpHandler的责任委托给ServiceStack,然后将返回的处理程序包装在新的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);
    }

}

然后,只需将Web.config中的处理程序中的type属性更改为SessionHttpHandlerFactory而不是ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack,您的web服务现在应该可以使用ASP.NET会话了。

尽管如此,我还是完全赞同ServiceStack提供的新的ISession实现。然而,在某些情况下,在一个成熟的产品上,用新的实现替换ASP.NET会话的所有用法似乎是一项太大的工作,因此才有了这个变通方法!

票数 18
EN

Stack Overflow用户

发布于 2015-12-16 01:28:36

感谢@Richard在上面的回答。我正在运行一个新版本的服务堆栈,他们已经删除了带有HttpFactory的ServiceStackHttpFactory。而不是让

private readonly static ServiceStackHttpHandlerFactory factory = new ServiceStackHttpHandlerFactory();

你需要有

private static readonly HttpHandlerFactory Factory = new HttpHandlerFactory();

以下是此服务的更新代码

using ServiceStack;
using System.Web;
using System.Web.SessionState;

namespace MaryKay.eCommerce.Mappers.AMR.Host
{
public class SessionHttpHandlerFactory : IHttpHandlerFactory
{
    private static readonly HttpHandlerFactory Factory = new HttpHandlerFactory();
    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);
    }
}

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

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

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

    public void ProcessRequest(HttpContext context)
    {
        Handler.ProcessRequest(context);
    }
}
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8339584

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档