Публикация потока в веб-API ASP.NET Core

Привет, милые люди из Stack Overflow. Со вчерашнего дня у меня проблема, и с тех пор я просматриваю ТАК. У меня есть клиент UWP и веб-API ASP.NET Core. Я просто хочу отправить поток на свой веб-API, но на самом деле это оказалось более сложной задачей, чем я думал.

У меня есть класс, у которого есть только одно свойство. Свойство Stream, как вы можете видеть ниже:

public class UploadData
{
    public Stream InputData { get; set; }
}

Тогда вот мой код из моего веб-API:

// POST api/values
[HttpPost]
public string Post(UploadData data)
{
    return "test";
}

Я попытался прочитать поток From body, но результат тот же. Я могу нажать на метод post UploadData не равно нулю, но мой InputData всегда null.

Вот мой код UWP для почтового запроса.

private async void PostStreamButton_OnClick(object sender, RoutedEventArgs e)
{
    using (var client = new HttpClient())
    {
        var dummyBuffer = new UnicodeEncoding().GetBytes("this is dummy stream");
        var dummyStream = new MemoryStream(dummyBuffer).AsRandomAccessStream().AsStream();

        var requestContent = new MultipartFormDataContent();
        var inputData = new StreamContent(dummyStream);
        inputData.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        requestContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

        requestContent.Add(inputData, "inputData");

        HttpResponseMessage response = client.PostAsync("url", inputData).Result;
    }
}

Я пробовал разные типы контента, но ни один из них не работает, и я понятия не имею, почему. Я был бы очень признателен за любую помощь.


person Hasan Hasanov    schedule 16.02.2017    source источник


Ответы (1)


На стороне клиента отправляйте содержимое потока, а не всю модель.

private async void PostStreamButton_OnClick(object sender, RoutedEventArgs e) {
    using (var client = new HttpClient()) {
        var dummyBuffer = new UnicodeEncoding().GetBytes("this is dummy stream");
        var dummyStream = new MemoryStream(dummyBuffer).AsRandomAccessStream().AsStream();

        var inputData = new StreamContent(dummyStream);

        var response = await client.PostAsync("url", inputData);
    }
}

ПРИМЕЧАНИЕ. Не смешивайте .Result блокирующие вызовы с асинхронными вызовами. Это, как правило, приводит к тупикам.

При обновлении сервера

// POST api/values
[HttpPost]
public IActionResult Post() {
    var stream = Request.Body;
    return Ok("test");
}
person Nkosi    schedule 16.02.2017
comment
Здравствуйте, в моем запросе нет свойства Content. У меня есть только тело. - person Hasan Hasanov; 16.02.2017
comment
@HasanHasanov, Вы правы. Мой код был для предыдущей версии. Тело - это то, что вам следует искать. - person Nkosi; 16.02.2017
comment
Из любопытства, как это работает за кадром. Когда вы получаете StreamContent (или любую другую потоковую вещь) в качестве ввода / вывода вызова службы, остается ли запрос / ответ открытым до тех пор, пока вы не удалите объект потока? Пытаюсь представить себе, как это работает за кулисами. - person Jeremy Armstrong; 13.04.2018
comment
@JeremyArmstrong взгляните на StreamContent для клиентской стороны. обратите внимание на SerializeToStreamAsync метод - person Nkosi; 13.04.2018
comment
На стороне сервера он сохраняет поток открытым до тех пор, пока он не будет выполнен с запросом. если он закроет его до завершения запроса / ответа, не все данные будут отправлены. - person Nkosi; 13.04.2018
comment
Когда он держит поток открытым, я предполагаю, что он оставляет запрос / ответ открытым, чтобы продолжать передачу данных, правильно? Я предполагаю, что он делает это, а не открывает другое соединение с сервером / клиентом для потока. - person Jeremy Armstrong; 14.04.2018