[英]HttpResponseMessage to string
我正在调用一个返回Task的方法,在调用方法中我需要以字符串的形式读取响应。
这是我放的代码:
static public async Task<HttpResponseMessage> Validate(string baseUri,HttpContent content) {
HttpResponseMessage response = new HttpResponseMessage();
response = await client.PostAsync(baseUri,content);
return response;
}
public string test(){
string postJson = "{Login = \"user\", Password = \"pwd\"}";
HttpContent stringContent = new StringContent(postJson,
UnicodeEncoding.UTF8, "application/json");
HttpResponseMessage result=Validate(Uri,stringContent);
var json = result.Content.ReadAsStringAsync().Result;
}
我期望字符串,但抛出此错误:
Cannot implicitly convert type
'System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage>' to
'System.Net.Http.HttpResponseMessage'
你的问题是:
HttpResponseMessage result=Validate(Uri,stringContent);
Validate
是返回任务,而不是HttpResponseMessage
。
改为:
var result = Validate(Uri,stringContent).Result;
只是为了清理代码并避免使用Result
如果你有能力改变它,如:
static public async Task<HttpResponseMessage> Validate(string baseUri, HttpContent content)
{
return await client.PostAsync(baseUri,content);
}
public async Task<string> test()
{
var postJson = "{Login = \"user\", Password = \"pwd\"}";
var stringContent = new StringContent(postJson, UnicodeEncoding.UTF8, "application/json");
var result = await Validate(Uri,stringContent);
return await result.Content.ReadAsStringAsync();
}
与您的编码风格保持一致。 至于为什么要调用.Result
是坏的,正如人们在评论中指出的那样,请查看此博客 。
只是为了可读性,将方法名称从Validate(..)
更改为ValidateAsync(..)
。 只是要明确这个方法返回一个任务,你必须等待它。
在调用Validate方法时,您错过了等待。 如果您不想或可以使调用者异步,那么使用方法GetAwaiter().GetResult()
,您将得到您想要的。
替换ReadAsStringAsync().Result
与ReadAsStringAsync().GetAwaiter().GetResult()
像其他人一样在评论中写道.Result
很糟糕,因为它可能导致锁定。 这同样适用于GetAwaiter().GetResult()
但调用它们比调用Result
更GetAwaiter().GetResult()
。 最好的选择是使用await/async
。
当你想知道GetAwaiter().GetResult()
vs调用Result
之间的区别时你可以读到: Task.Result与.GetAwaiter.GetResult()相同吗?
方法Validate
返回任务并且是异步的。 基本上你可以用两种不同的方式调用这个方法:
1)在另一个异步方法中等待Validate
的结果,像这样......
public async Task<string> test() {
string postJson = "{Login = \"user\", Password = \"pwd\"}";
HttpContent stringContent = new StringContent(postJson,
UnicodeEncoding.UTF8, "application/json");
HttpResponseMessage result = await Validate(Uri,stringContent);
var json = result.Content.ReadAsStringAsync().Result;
}
2)在等待这个结果时阻止当前执行,像这样......
public string test() {
string postJson = "{Login = \"user\", Password = \"pwd\"}";
HttpContent stringContent = new StringContent(postJson,
UnicodeEncoding.UTF8, "application/json");
HttpResponseMessage result = Validate(Uri,stringContent).Result;
var json = result.Content.ReadAsStringAsync().Result;
}
默认选择第一种方式,除非你真的有阻止调用线程的冲动。
请注意,在WinForms,WPF或ASP.NET应用程序中使用第二个解决方案时,您可能会遇到死锁。 像这样修改Validate
方法应该可以解决问题:
response = await client.PostAsync(baseUri,content).ConfigureAwait(false);
您可以轻松编写: var json = result.Content.ReadAsStringAsync().GetAwaiter().GetResult();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.