54

ApiControllerクラスに次のWebAPIメソッドがあります。

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

incomingDataPOSTの生のコンテンツになりたいです。しかし、Web APIスタックがJSONフォーマッターを使用して受信データを解析しようとしているようです。これにより、クライアント側の次のコードが失敗します。

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

これに対する簡単な回避策はありますか?

4

7 に答える 7

58

この問題が発生した他の人にとっての解決策は、パラメーターなしでPOSTメソッドを定義し、次の方法で生データにアクセスすることRequest.Contentです。

public HttpResponseMessage Post()
{
  Request.Content.ReadAsByteArrayAsync()...
  ...
于 2012-11-06T09:51:08.817 に答える
37

アクセスを容易にするためにモデルパラメータに加えて生の入力が必要な場合は、次を使用できます。

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)、データを読み取ろうとする前にストリームをリセットするために使用しています。

于 2016-07-11T10:18:06.367 に答える
18

他の回答は、入力パラメーターを削除することを提案していますが、それは既存のコードをすべて壊してしまいます。質問に正しく答えるためのより簡単な解決策は、次のような関数を作成することです(このコードについては以下のChristophに感謝します)。

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

次に、次のようにWebAPI呼び出し内で生の投稿データを取得します。

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

    // log it or whatever

    return Request.CreateResponse(HttpStatusCode.OK);
}
于 2016-07-20T03:39:35.953 に答える
13

MVC 6では、リクエストに「コンテンツ」プロパティがないようです。これが私がやったことです:

[HttpPost]
public async Task<string> Post()
{
    string content = await new StreamReader(Request.Body).ReadToEndAsync();
    return "SUCCESS";
}
于 2016-03-17T02:23:21.520 に答える
11

私は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の任意のメソッドから次のように呼び出すことができます。

string raw = await RawContentReader.Read(this.Request);
于 2016-11-15T21:22:28.063 に答える
1

または単に

string rawContent = await Request.Content.ReadAsStringAsync();

元のリクエストが破棄される前に、同じスレッドで上記の行を実行していることを確認してください

注:これはASP.NETMVC5用です

于 2021-02-22T09:02:59.610 に答える
0

以下のコントローラーで、codeBlockはリクエスト本文の生のペイロードを取得します

 string requestBody = string.Empty;
        using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
        {
            requestBody = await reader.ReadToEndAsync();
        }
于 2021-10-15T19:09:58.953 に答える