Получение содержимого из HttpResponseMessage для тестирования с использованием динамического ключевого слова c#

в одном из действий, я делаю что-то вроде этого

public HttpResponseMessage Post([FromBody] Foo foo)
{
    .....
    .....

    var response = 
          Request.CreateResponse(HttpStatusCode.Accepted, new { Token = "SOME_STRING_TOKEN"});
    return response;
}

и другие подобные методы возвращают экземпляр анонимного типа, и он работает хорошо.

сейчас я пишу тесты для него. У меня

HttpResponseMessage response = _myController.Post(dummyFoo);

HttpResponseMessage есть свойство под названием Content и ReadAsAsync<T>().

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

Bar bar = response.Content.ReadAsAsync<Bar>();

но как мне получить доступ к анонимному типу, который возвращение? Возможно ли это?

Я надеялся сделать следующее:

dynamic responseContent = response.Content.ReadAsAsync<object>();
string returnedToken = responseContent.Token;

но я получил ошибку, что экземпляр типа object не имеет маркера свойства. Это происходит, даже если отладчик показывает responseContent с одним маркером свойства. Я понимаю, почему это происходит, но я хочу знать, есть ли способ получить доступ к собственности.

enter image description here

спасибо

1 ответов


.ReadAsAsync<T> является асинхронным методом, что означает, что он не возвращает весь десериализованный объект, а Task<T> для обработки продолжения всей асинхронной задачи.

у вас есть два варианта:

1. Асинхронный шаблон.

использовать async ключевое слово в вашем методе enclousing (например: public async void A()) и выполните асинхронный вызов следующим образом:

dynamic responseContent = await response.Content.ReadAsAsync<object>();
string returnedToken = responseContent.Token;

2. Обычная задача API

или просто используйте задачу API:

response.Content.ReadAsAsync<object>().ContinueWith(task => {
   // The Task.Result property holds the whole deserialized object
   string returnedToken = ((dynamic)task.Result).Token;
});

это зависит от вас!

обновление

прежде чем вы разместили весь скриншот, никто не мог знать, что вы звоните task.Wait для того, чтобы дождаться асинхронного результата. Но я собираюсь сохранить свой ответ, потому что это может помочь дальнейшим посетителям:)

как я предложил в комментарии к моему собственному ответу, вы должны попробовать десериализоваться в ExpandoObject. ASP.NET WebAPI использует JSON.NET в качестве базового сериализатора JSON. То есть, он может обрабатывать анонимные Десериализация объектов JavaScript в объекты expando.