如何获取已读取的内容

Hal*_*ard 19 c# asp.net asp.net-web-api

我有一个继承自ApiController的类.它有一个像这样的Put方法:

[PUT("user/{UserId}")]
public HttpResponseMessage Put(string userId, PaymentRequest paymentRequest)
{
    // Calling business logic and so forth here
    // Return proper HttpResponseMessage here
}
Run Code Online (Sandbox Code Playgroud)

该方法在上面工作正常.现在我需要验证方法调用的签名,但在这里我遇到了一个问题.签名本质上是方法+ url + body的组合.我可以通过调用Request.Method和我可以通过调用Request.RequestUri.ToString()得到的url获得的方法,但是我无法得到它之前的身体,因为它被自动反序列化为PaymentRequest对象之前 asp.net MVC4框架.

我的第一次尝试: 因为我现在已经理解了Request.Content.ReadAsStringAsync().结果什么也没有返回.这是因为内容只能读取一次.

我的第二次尝试: 我尝试将其序列化为JSON字符串.

var serializer = new JavaScriptSerializer();
var paymentRequestAsJson = serializer.Serialize(paymentRequest);
Run Code Online (Sandbox Code Playgroud)

这个问题是格式化与签名的正文部分略有不同.它具有相同的数据,但有一些空格.

我无法改变Put-method的调用者所做的事情,因为这是第三方组件.我该怎么办?

Dar*_*rov 34

您可以从底层请求中读取:

using (var stream = new MemoryStream())
{
    var context = (HttpContextBase)Request.Properties["MS_HttpContext"];
    context.Request.InputStream.Seek(0, SeekOrigin.Begin);
    context.Request.InputStream.CopyTo(stream);
    string requestBody = Encoding.UTF8.GetString(stream.ToArray());
}
Run Code Online (Sandbox Code Playgroud)

  • 因为没有这样的属性`Request.InputStream`.不要忘记,在ApiController中,Request属性的类型是`HttpRequestMessage`而不是'HttpRequestBase`. (3认同)
  • MS_HttpContext对我来说不存在 (3认同)

Dar*_*ler 16

不要在签名中包含body参数,这样您就可以根据需要缓冲内容并多次读取内容.

[PUT("user/{UserId}")]
public HttpResponseMessage Put(string userId)
{
    Request.Content.LoadIntoBufferAsync().Wait();
    var paymentRequest = Request.Content.ReadAsAsync<PaymentRequest>().Result;
    var requestBody = Request.Content.ReadAsStringAsync().Result;
    // Calling business logic and so forth here
    // Return proper HttpResponseMessage here
}
Run Code Online (Sandbox Code Playgroud)