从HttpResponseMessage获取内容以使用c#动态关键字进行测试

Pro*_*aos 12 c# unit-testing asp.net-web-api

在其中一个动作中,我做了类似的事情

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

    var response = 
          Request.CreateResponse(HttpStatusCode.Accepted, new { Token = "SOME_STRING_TOKEN"});
    return response;
}
Run Code Online (Sandbox Code Playgroud)

以及更多像这样返回匿名类型实例的方法,它运行良好.

现在,我正在为它编写测试.我有

HttpResponseMessage response = _myController.Post(dummyFoo);
Run Code Online (Sandbox Code Playgroud)

HttpResponseMessage有一个叫做的房产Content,有一个ReadAsAsync<T>().

我知道如果有具体的具体类型,我可以做到

Bar bar = response.Content.ReadAsAsync<Bar>();
Run Code Online (Sandbox Code Playgroud)

但是如何访问正在返回的匿名类型?可能吗?

我希望做到以下几点:

dynamic responseContent = response.Content.ReadAsAsync<object>();
string returnedToken = responseContent.Token;
Run Code Online (Sandbox Code Playgroud)

但我收到错误,类型对象的实例没有属性令牌.即使调试器显示带有一个属性Token的responseContent,也会发生这种情况.我理解为什么会这样,但我想知道是否有办法访问该属性.

在此输入图像描述

谢谢

Mat*_*zer 12

.ReadAsAsync<T>是一个异步方法,这意味着它不返回整个反序列化对象,而是一个Task<T>处理整个异步任务的延续.

你有两个选择:

1.异步模式.

async在封闭方法中使用关键字(例如:) public async void A(),并以这种方式执行异步调用:

dynamic responseContent = await response.Content.ReadAsAsync<object>();
string returnedToken = responseContent.Token;
Run Code Online (Sandbox Code Playgroud)

2.常规任务API

或者只使用Task API:

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

由你决定!

更新

在您发布整个屏幕截图之前,没有人知道您正在调用task.Wait以等待异步结果.但我会保持我的答案,因为它可能会帮助更多的访客:)

正如我在评论中建议的那样,你应该尝试反序列化ExpandoObject.ASP.NET WebAPI使用JSON.NET作为其底层JSON序列化程序.也就是说,它可以处理对expando对象的匿名JavaScript对象反序列化.