2012-11-05 16 views
30

からの生のPOSTデータの取得:私はApiControllerクラスに次のWeb APIメソッド持つウェブAPIメソッド

public HttpResponseMessage Post([FromBody]byte[] incomingData) 
{ 
    ... 
} 

を私はincomingDataは、POSTの生のコンテンツになりたいです。しかし、それは、Web APIスタックはJSONフォーマッタに入ってくるデータを解析しようとすると、これは、クライアント側で次のコードが失敗しているようです:

new WebClient().UploadData("http://localhost:15134/api/Foo", new byte[] { 1, 2, 3 }); 

このため、簡単な回避策はありますか?

この問題に実行している他の誰のために

答えて

39

、解決策は、パラメータなしでPOSTメソッドを定義し、Request.Content経由で生のデータにアクセスすることです:MVC 6のリクエストで

+3

私は似たような必要はなく、文字列のために、とPOSTメソッドにはパラメータがありませんでした保証することに不可欠なことになりました同等の 'ReadAsStringAsync'を使用すると、それはそうでなければ空であった。 –

+0

これは私が見つけたこれを行う最も簡単な方法です。私たちのパートナーは、私たちが使いたいと思っている文書化されていない新しいフィールドを追加し続けています。ありがとう! – MvcCmsJon

+0

ありがとうございます。フルボディを得るためのMVC6では、パラメータを削除し、 'Request.Body'を手動で読み込まなければなりませんでした。 – joe

3

は持っていないようです'Content'プロパティ。ここに私がやってしまったものです:

[HttpPost] 
public async Task<string> Post() 
{ 
    string content = await new StreamReader(Request.Body).ReadToEndAsync(); 
    return "SUCCESS"; 
} 
19

あなたは簡単にアクセスのためのモデルパラメータに加えて、生の入力が必要な場合は、以下を使用することができます。

using (var contentStream = await this.Request.Content.ReadAsStreamAsync()) 
{ 
    contentStream.Seek(0, SeekOrigin.Begin); 
    using (var sr = new StreamReader(contentStream)) 
    { 
     string rawContent = sr.ReadToEnd(); 
     // use raw content here 
    } 
} 

秘密をリセットするためにstream.Seek(0, SeekOrigin.Begin)を使用していますデータを読み込もうとする前のストリーム

+0

これをお寄せいただきありがとうございます。あなたのコードに基づいて回答を投稿しました。もしあなたがそれを自由に組み入れたいのであれば、私は自分の答えを削除します。 – Rocklan

10

他の回答は、入力パラメータを削除することをお勧めしますが、これは既存のコードをすべて破棄します。その後、

private async Task<String> getRawPostData() 
{ 
    using (var contentStream = await this.Request.Content.ReadAsStreamAsync()) 
    { 
     contentStream.Seek(0, SeekOrigin.Begin); 
     using (var sr = new StreamReader(contentStream)) 
     { 
      return sr.ReadToEnd(); 
     } 
    } 
} 

生がそうのようなあなたのWeb API呼び出し内のデータを掲載取得:適切に質問に答えるために、より容易な解決策は次のようになります関数を作成する(以下、このコードのクリストフのおかげで)です。

public HttpResponseMessage Post ([FromBody]byte[] incomingData) 
{ 
    string rawData = getRawPostData().Result; 

    // log it or whatever 

    return Request.CreateResponse(HttpStatusCode.OK); 
} 
+1

素敵な仕事、ありがとう!私は静的メソッドを持つユーティリティクラスとしてあなたを逆戻りさせる答えを追加しています。 –

+3

笑、今我々は3つのレベルの深いです。 – Rocklan

+0

タスク .Resultプロパティにアクセスすると、すぐにスレッドで待機します。ここでタスクを使用することに利点はありますか? – codinglifestyle

3

私はLachlanBの答えをすべてのコントローラで使用できる単一の静的メソッドでユーティリティクラスに入れました。

public class RawContentReader 
{ 
    public static async Task<string> Read(HttpRequestMessage req) 
    { 
     using (var contentStream = await req.Content.ReadAsStreamAsync()) 
     { 
      contentStream.Seek(0, SeekOrigin.Begin); 
      using (var sr = new StreamReader(contentStream)) 
      { 
       return sr.ReadToEnd(); 
      } 
     } 
    } 
} 

その後、私は私のApiControllerの方法のいずれかから、このようにそれを呼び出すことができます。

関連する問題