我有一个继承自ApiController的类。它有一个像这样的Put-method:
[PUT("user/{UserId}")]
public HttpResponseMessage Put(string userId, PaymentRequest paymentRequest)
{
// Calling business logic and so forth here
// Return proper HttpResponseMessage here
}
如上所述,该方法工作得很好。现在我需要验证方法调用的签名,但在这里我遇到了一个问题。签名本质上是method + url + body的组合。我可以通过调用Request.Method获得的方法和通过调用Request.RequestUri.ToString()获得的url,但我无法获得主体,因为它在之前是它被asp.net MVC4框架自动反序列化为PaymentRequest对象。
我的第一次尝试:,正如我现在所理解的,Request.Content.ReadAsStringAsync().Result不返回任何内容。这是因为内容只能读取一次。
我的第二次尝试是:,我尝试将其序列化为字符串。
var serializer = new JavaScriptSerializer();
var paymentRequestAsJson = serializer.Serialize(paymentRequest);
这样做的问题是,格式化结果与签名的正文部分略有不同。它有相同的数据,但有更多的空间。
我不能改变Put-method的调用者所做的事情,因为这是一个第三方组件。我该怎么办?
发布于 2012-08-10 21:00:17
您可以从底层请求中读取:
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());
}
发布于 2012-08-11 04:25:59
不要在签名中包含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
}
发布于 2016-10-30 13:48:25
一个非常延迟的响应,但最近我也有同样的挑战需要克服。
我已经接近了这一点,而不必从httpContext获取数据(对于大容量事务web应用程序来说,这可能是相当昂贵的)。
我创建了一个简单的接口,并让每个控制器实现它:
public interface IBaseControllerData
{
object Entity { get; set; }
}
然后,我将控制器的Entity属性设置为每个post和put操作的Json有效负载。最后,我检索了被ActionFilterAttribute.OnActionExecuted覆盖的方法中的实体数据,并在注入MongoDB之前将其序列化为Json:
object entity = ((IBaseControllerData)actionExecutedContext.ActionContext.ControllerContext.Controller).Entity;
requestBody = Newtonsoft.Json.JsonConvert.SerializeObject(entity);
希望这能有所帮助!
干杯
https://stackoverflow.com/questions/11901906
复制相似问题