我刚刚开始使用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实现,以使事情正常工作,并避免在这一点上超过必要的重写。
发布于 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中,并使用自定义请求过滤器实现。
以下是我多年来使用的不同身份验证策略:
时,一种合适的方法
发布于 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会话的所有用法似乎是一项太大的工作,因此才有了这个变通方法!
发布于 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);
}
}
}
https://stackoverflow.com/questions/8339584
复制相似问题