[英]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.