在其中一个动作中,我做了类似的事情
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类型的实例没有属性Token。即使调试器显示带有一个属性Token的responseContent,也会发生这种情况。我理解为什么会这样,但我想知道是否有办法访问该物业。
由于
答案 0 :(得分:12)
.ReadAsAsync<T>
是一个异步方法,这意味着它不返回整个反序列化对象,而是返回Task<T>
来处理整个异步任务的继续。
您有两种选择:
在封闭方法中使用async
关键字(例如:public async void A()
)并以这种方式进行异步调用:
dynamic responseContent = await response.Content.ReadAsAsync<object>();
string returnedToken = responseContent.Token;
或者只使用Task 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序列化程序。也就是说,它可以处理对expando对象的匿名JavaScript对象反序列化。
答案 1 :(得分:0)
您还可以使用类似的以下代码通过单元测试来测试HttpResponseMessage。
这对我有用。
希望这对您有帮助
[TestClass]
public class UnitTest
{
[TestMethod]
public void Post_Test()
{
//Arrange
var contoller = new PostController(); //the contoller which you want to test
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
// Act
var response = controller.Post(new Number { PhNumber = 9866190822 });
// Number is the Model name and PhNumber is the Model Property for which you want to write the unit test
//Assert
var request = response.StatusCode;
Assert.AreEqual("Accepted", request.ToString());
}
}
类似地,根据需要在Assert中更改HttpResponseMessage。