问题 ServiceStack Runner可以获取请求正文吗?


是否可以在没有重大hackery的情况下在Runner中获取ServiceStack请求的原始请求主体?

我正在编写一个oauth服务提供程序,使用新的API(Service and Runner)在ServiceStack上运行。由于OAuth签名的工作方式,我需要为每个请求获取原始请求正文。 OAuth保护层已添加到Runner中,因此无效的OAuth请求可以轻松返回空/错误响应,而无需Service类中的任何样板或子类化特殊的“OAuthService”类。


11808
2017-07-07 18:01


起源



答案:


访问Raw Request Body的方法是使用 IHttpRequest.GetRawBody() 或阅读 IHttpRequest.InputStream

但由于HTTP请求主体是仅前向流,因此默认情况下它只能被调用一次,这通常由ServiceStack调用以反序列化请求DTO。该 序列化和反序列化文档 展示如何告诉ServiceStack跳过反序列化请求并将未读请求流注入请求DTO:

public class Hello : IRequiresRequestStream
{
    /// <summary>
    /// The raw Http Request Input Stream
    /// </summary>
    Stream RequestStream { get; set; }
}

如果您仍希望ServiceStack反序列化Request DTO,但也访问原始请求体,则需要告诉ServiceStack在读取之前缓冲请求,您可以通过添加PreRequestFilter来执行此操作:

appHost.PreRequestFilters.Insert(0, (httpReq, httpRes) => {
    httpReq.UseBufferedStream = true;
});

现在让你打电话 httpReq.GetRawBody() 多次或直接从中读取 IHttpRequest.InputStream 因为它现在被缓冲了。


15
2017-07-07 18:24



这或多或少都是我已经在做的事情,但我不得不使用反射来从IRequestContext获取IHttpRequest,我不愿意这样做,原因很明显。有没有办法从IServiceRunner <TRequest> .Execute方法中获取IHttpRequest? - John Carruthers
反射?做就是了 requestContext.Get<IHttpRequest>() 得到请求。 - mythz
@mythz是安全的 httpReq.UseBufferedStream = true; 在生产?或者这通常不推荐? - vonec
@vonec没关系,它只是缓冲请求流,以便可以重读请求体。 - mythz


答案:


访问Raw Request Body的方法是使用 IHttpRequest.GetRawBody() 或阅读 IHttpRequest.InputStream

但由于HTTP请求主体是仅前向流,因此默认情况下它只能被调用一次,这通常由ServiceStack调用以反序列化请求DTO。该 序列化和反序列化文档 展示如何告诉ServiceStack跳过反序列化请求并将未读请求流注入请求DTO:

public class Hello : IRequiresRequestStream
{
    /// <summary>
    /// The raw Http Request Input Stream
    /// </summary>
    Stream RequestStream { get; set; }
}

如果您仍希望ServiceStack反序列化Request DTO,但也访问原始请求体,则需要告诉ServiceStack在读取之前缓冲请求,您可以通过添加PreRequestFilter来执行此操作:

appHost.PreRequestFilters.Insert(0, (httpReq, httpRes) => {
    httpReq.UseBufferedStream = true;
});

现在让你打电话 httpReq.GetRawBody() 多次或直接从中读取 IHttpRequest.InputStream 因为它现在被缓冲了。


15
2017-07-07 18:24



这或多或少都是我已经在做的事情,但我不得不使用反射来从IRequestContext获取IHttpRequest,我不愿意这样做,原因很明显。有没有办法从IServiceRunner <TRequest> .Execute方法中获取IHttpRequest? - John Carruthers
反射?做就是了 requestContext.Get<IHttpRequest>() 得到请求。 - mythz
@mythz是安全的 httpReq.UseBufferedStream = true; 在生产?或者这通常不推荐? - vonec
@vonec没关系,它只是缓冲请求流,以便可以重读请求体。 - mythz