web-dev-qa-db-ja.com

ASP.NET Web API ValueProviderのHTTP POSTリクエストから本文の値を取得するにはどうすればよいですか?

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を探求しているので、それを機能させるのはいいことです。

私の問題は、リクエスト本文が保存されている場所が見つからないことです。

ご指導ありがとうございます!

12
Jim Aho

これはRick Strahlからの ブログ投稿 についての記事です。彼の投稿はほとんどあなたの質問に答えます。彼のコードをニーズに合わせるには、次のようにします。

値プロバイダーのコンストラクター内で、次のようにリクエストの本文を読み取ります。

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

ロギングのために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)
        };
0
ColinM