如何从 ServiceStack 中的自定义序列化程序访问 IHttpRequest
本文关键字:序列化 程序 访问 IHttpRequest 自定义 ServiceStack | 更新日期: 2023-09-27 17:55:40
我们为模型提供了自定义序列化程序,可根据请求路径保护敏感数据。(例如,如果请求不以"/admin"开头)。
到目前为止,我们已经尝试使用 ReuseScope.None 或 ReuseScope.Request 在 RequestFilter 上向 Funq 容器注册 IHttpRequest,在序列化程序上,我们从容器中获取 IHttpRequest。
我们发现,如果有多个请求挂起,容器将返回最后一个注册的 IHttpRequest,这并不总是正确的请求对象。
我知道我们可以尝试使用过滤器属性在我们的模型上实现对敏感数据的这种保护,但这非常麻烦,因为我们的模型对象通常嵌入在其他对象或集合中。
让序列化程序来做到这一点对我们来说是迄今为止最好的解决方案,如果不是因为无法从序列化程序中获取正确的 HttpRequest 对象的问题。
那么,正确的方法是什么?还是这是一种不好的做法?
下面是一些代码示例:
因此,这是我的序列化程序用来定义它们是否在"admin"路由中序列化的私有方法:
private bool IsAdminRoute() {
var path = container.Resolve<IHttpRequest> ().PathInfo;
var res = path.StartsWith ("/admin");
return res;
}
这是它的用法:
public Question QuestionSerializer(Question question)
{
if (!IsAdminRoute())
{
// do stuff like nullyfying certain properties
}
return question;
}
在我的AppHost初始化中,我有:
void ConfigureSerializers(Funq.Container container)
{
Serializers = new CustomSerializers ();
// ...
JsConfig<Question>.OnSerializingFn = Serializers.QuestionSerializer;
// ...
}
public void HttpRequestFilter(IHttpRequest httpReq, IHttpResponse httpRes, object dto) {
Container.Register <IHttpRequest>(c => httpReq).ReusedWithin (Funq.ReuseScope.Request);
}
注意:我使用的是 ServiceStack v3。
我设法通过以这种方式注册IHttpRequest来使其工作:
container.Register(c => HttpContext.Current.ToRequestContext ().Get<IHttpRequest>()).ReusedWithin(Funq.ReuseScope.None);
现在,当我尝试解析它们时,我总是会得到我应该得到的 IHttpRequest 对象。
此外,在我的应用程序中进行了更彻底的测试后,我能够检测到,如果并发性足够高,依赖于向 ReuseScope.Request 注册的所有内容都会变得混乱。
解决方案非常简单,我现在依靠 HttpContext.Current.Items 集合来存储这些特定于请求的依赖项,并将它们注册到请求过滤器上,如下所示:
HttpContext.Current.Items ["Token"] = token;
container.Register<Token> (c => (Token)HttpContext.Current.Items["Token"]).ReusedWithin(Funq.ReuseScope.None);
现在它每次都按预期工作。