【问题标题】:How do I retrieve body values from an HTTP POST request in an ASP.NET Web API ValueProvider?如何从 ASP.NET Web API ValueProvider 中的 HTTP POST 请求中检索正文值?
【发布时间】:2014-05-18 01:16:01
【问题描述】:

我想发送一个 HTTP POST 请求,其正文包含构成简单博客文章的信息,没什么花哨的。

我读过here,当您想在Web API 中绑定复杂类型(即不是stringint 等的类型)时,一个好方法是创建自定义模型绑定器。

我有一个自定义模型绑定器 (BlogPostModelBinder),它又使用自定义值提供程序 (BlogPostValueProvider)。我不明白的是,我应该如何以及在哪里能够从BlogPostValueProvider 中的请求正文中检索数据?

在模型绑定器中,我认为这是检索标题的正确方法。

public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
   ...
   var title= bindingContext.ValueProvider.GetValue("Title");
   ...
}

虽然 BlogPostValueProvider 看起来像这样:

 public class BlogPostValueProvider : IValueProvider
 {
    public BlogPostValueProvider(HttpActionContext actionContext)
    {
       // I can find request header information in the actionContext, but not the body.
    }

    public ValueProviderResult GetValue(string key)
    {
       // In some way return the value from the body with the given key.
    }
 }

这可能会以更简单的方式解决,但由于我正在探索 Web API,让它工作会很好。

我的问题只是我找不到请求正文的存储位置。

感谢您的指导!

【问题讨论】:

  • 您的请求内容类型是什么...我假设是formurlencoded?...您能否详细说明为什么需要自定义模型绑定器...
  • 如果您发布的是 BlogPostVM 的 json,那么您只需要一个接受 BlogPostVM 的操作,不需要自定义活页夹。
  • 我认为你们都是正确的。请求中的 ContentType 设置为 json @KiranChalla。有一个带有 BlogPost 类型参数的操作可能会做到这一点。我仍然想知道为什么我无法从值提供者中访问请求正文。
  • @KiranChalla 我认为我不需要自定义模型活页夹。我是 Web API 的新手,所以它更像是一种探索性的方式。
  • Web API 中请求/响应的模型绑定或反序列化由 Content-Type 标头和媒体类型格式化程序驱动。当请求的内容类型被格式化编码时,FormUrlEncodedMediaTypeFormatter 将处理请求正文以执行任何它想要的操作。在此过程中,IModelBinderIValueProvider 出现,而​​在 json 的情况下,它由 JsonMediaTypeFormatter 处理,这又取决于 JSON.Net 的反序列化器。这个解串器没有模型绑定器或值提供者的概念。

标签: c# asp.net asp.net-web-api model-binding value-provider


【解决方案1】:

这是来自 Rick Strahl 的 blog post。他的帖子几乎回答了你的问题。要使他的代码适应您的需要,您可以执行以下操作。

在您的值提供者的构造函数中,像这样读取请求正文。

Task<string> content = actionContext.Request.Content.ReadAsStringAsync();
string body = content.Result;

【讨论】:

  • 永远不要使用 .Result,总是使用 await 否则你会遇到死锁/饥饿
【解决方案2】:

我需要在 ActionFilterAttribute 中执行此操作以进行日志记录,我找到的解决方案是使用 actionContext 中的 ActionArguments,如下所示

public class ExternalApiTraceAttribute : ActionFilterAttribute
{


    public override void OnActionExecuting(HttpActionContext actionContext)
    {
       ...

        var externalApiAudit = new ExternalApiAudit()
        {

            Method = actionContext.Request.Method.ToString(),
            RequestPath = actionContext.Request.RequestUri.AbsolutePath,
            IpAddresss = ((HttpContextWrapper)actionContext.Request.Properties["MS_HttpContext"]).Request.UserHostAddress,
            DateOccurred = DateTime.UtcNow,
            Arguments = Serialize(actionContext.ActionArguments)
        };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-26
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 2020-07-06
    相关资源
    最近更新 更多