Почему ResponseMessage.Содержимое неизменно пусто после запроса await PostAsJsonAsync?

#c# #asynchronous #async-await

#c# #асинхронный #async-ожидание

Вопрос:

Мы отправляем «maintenanceEvent» в API, который последовательно возвращает [] в ResponseMessage.Содержание. Мне понадобилось бы руководство эксперта на случай, если код, который я написал здесь, неисправен.

 private async Task SendMaintenanceEvent(object maintenanceEvent, MaintenanceEventType maintenanceEventType)
{
    string endpointAddress = "TheEndpointURI";
    string credentials = "OurCredentials";
    string credentialsBase64 = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(credentials));

    // Convert the maintenanceEvent object to consumable JSON, then encode it to a StringContent object.
    this.responseInfo.MaintenanceEventAsJSON = System.Web.Helpers.Json.Encode(maintenanceEvent);
    StringContent stringContent = new StringContent(this.responseInfo.MaintenanceEventAsJSON, Encoding.UTF8, "application/json");
    using (HttpClient httpClient = new HttpClient())
    {
        httpClient.BaseAddress = new Uri(endpointAddress);
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentialsBase64);
        this.responseInfo.AuthorizationHeader = httpClient.DefaultRequestHeaders.Authorization.ToString();
        this.responseInfo.EndpointUri = httpClient.BaseAddress.AbsoluteUri;

        // The async post.
        this.responseInfo.ResponseMessage = await httpClient.PostAsJsonAsync(access.EndpointDirectory, stringContent).ConfigureAwait(false);

        this.responseInfo.ResponseStatusCode = (int)this.responseInfo.ResponseMessage.StatusCode;

        // Consistently returns true so long as my credentials are valid.
        // When the auth credentials are invalid, this returns false.
        if (this.responseInfo.ResponseMessage.IsSuccessStatusCode)
        {
            // I expect to see some data from the service.
            this.responseInfo.ResponseContent = this.responseInfo.ResponseMessage.Content.ReadAsStringAsync();
        }
    }
}
  

Блоки Try / Catch и некоторая информация о конкретной компании опущены. Объект responseInfo выше — это просто модель с некоторыми свойствами для сбора информации из этого метода, чтобы мы могли записать событие.

Я подозреваю, что проблема может быть в коде под командой PostAsJsonAsync. Но я в недоумении, что там делать. Спасибо за вашу помощь.

Комментарии:

1. Действительно ли ResponseContent имеет тип Task<string>? Если он имеет тип string, вам нужно дождаться ReadAsStringAsync() в этой строке.

2. Спасибо sellotape. Если я сделаю это, то как я могу присвоить результат строке? Я читаю об асинхронности и смотрел презентацию Стивена Тауба по ней. Я только что попробовал это и получил неявное предупреждение о преобразовании: var responseContentString = await this.responseInfo.ResponseMessage. Содержание. ReadAsStringAsync(); this.responseInfo.ResponseContent = responseContentString. toString();

3. Это не тип задачи<строка> . Итак, я попробовал это: Задача<строка> ответ = ожидание HttpClient. PostAsJsonAsync (доступ. EndpointDirectory, StringContent). ConfigureAwait(false); И теперь Intellisense показывает: «Не удается неявно преобразовать тип ‘System.Net.Http.HttpResponseMessage’ в ‘System. Многопоточность. Задачи. Задача<строка>’.

Ответ №1:

Это (слегка скорректированное) то, что вы хотите сделать (замените свои собственные переменные по мере необходимости):

 using (HttpClient httpClient = new HttpClient())
{
    // ...
    HttpResponseMessage responseMessage = await httpClient.PostAsJsonAsync(access.EndpointDirectory, stringContent).ConfigureAwait(false);
    // ...
    string responseBody = await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);
    // ...
}
  

Т.е. вы должны ожидать ReadAsStringAsync() , чтобы получить фактическое содержимое.

Для полноты картины обратите внимание, что HttpResponseMessage и HttpResponseMessage.Content являются IDisposable .

Комментарии:

1. sellotape, большое спасибо за вашу помощь. Я должен перейти в автономный режим на день, но вернусь утром, чтобы попробовать. Спасибо за подсказку IDisposable. Гарантированно ли выполняется строка ResponseBody после завершения строки ResponseMessage? Извините, поскольку асинхронность — это то, с чем я раньше не сталкивался в .NET. Мне было интересно, должно ли это быть в каком-то нижестоящем делегате. Спасибо за ваше терпение!

2. «Гарантированно ли выполняется строка ResponseBody после завершения строки ResponseMessage» — предполагая, что вы имеете в виду, что нет никаких шансов, что она попытается выполнить до завершения первой строки, тогда да, абсолютно (с первым таким ожиданием).

3. Спасибо за вашу помощь, sellotape!