如何获取已读取的内容

我有一个inheritance自ApiController的类。 它有一个像这样的Put方法:

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

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

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

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

 var serializer = new JavaScriptSerializer(); var paymentRequestAsJson = serializer.Serialize(paymentRequest); 

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

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

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

 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()); } 

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

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

一个非常迟缓的反应,但最近我遇到了同样的挑战需要克服。

我已经接近了一点点不同,无需从httpContext获取数据(对于高容量事务Web应用程序来说可能相当昂贵)。

我创建了一个简单的接口,并使每个Controller实现它:

 public interface IBaseControllerData { object Entity { get; set; } } 

然后,我将Controller的Entity属性设置为每个post的Json有效负载并执行操作。 最后,我在ActionFilterAttribute.OnActionExecuted重写方法中检索了Entity数据,并在注入MongoDB之前将其序列化为Json:

 object entity = ((IBaseControllerData)actionExecutedContext.ActionContext.ControllerContext.Controller).Entity; requestBody = Newtonsoft.Json.JsonConvert.SerializeObject(entity); 

希望有所帮助!

干杯