Подтвердить что ты не робот

Получение необработанных данных POST из метода Web API

У меня есть следующий метод Web API в классе ApiController:

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

Я хочу, чтобы incomingData был сырым содержимым POST. Но кажется, что стек Web API пытается проанализировать входящие данные с помощью форматирования JSON, и это приводит к сбою следующего кода на стороне клиента:

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

Есть ли простой способ обхода?

4b9b3361

Ответ 1

Для всех, кто работает в этой проблеме, решение состоит в том, чтобы определить метод POST без параметров и получить доступ к необработанным данным через Request.Content:

public HttpResponseMessage Post()
{
  Request.Content.ReadAsByteArrayAsync()...
  ...

Ответ 2

Если вам нужен необработанный ввод в дополнение к параметру модели для облегчения доступа, вы можете использовать следующее:

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) to reset, прежде чем пытаться прочитать данные.

Ответ 3

Другие ответы предлагают удалить входной параметр, но это сломает весь ваш существующий код. Чтобы правильно ответить на вопрос, более простым решением является создание функции, которая выглядит так (спасибо Кристофу ниже для этого кода):

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

а затем получить исходные размещенные данные внутри вашего веб-приложения api следующим образом:

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

    // log it or whatever

    return Request.CreateResponse(HttpStatusCode.OK);
}

Ответ 4

Я взял 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);

Ответ 5

В запросе MVC 6, похоже, нет свойства Content. Вот что я сделал:

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