簡體   English   中英

HttpResponseMessage 到字符串

[英]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是壞的,正如人們在評論中指出的那樣,請查看此博客

  1. 只是為了可讀性,將方法名稱從Validate(..)更改為ValidateAsync(..) 只是要明確這個方法返回一個任務,你必須等待它。

  2. 在調用Validate方法時,您錯過了等待。 如果您不想或可以使調用者異步,那么使用方法GetAwaiter().GetResult() ,您將得到您想要的。

  3. 替換ReadAsStringAsync().ResultReadAsStringAsync().GetAwaiter().GetResult()

像其他人一樣在評論中寫道.Result很糟糕,因為它可能導致鎖定。 這同樣適用於GetAwaiter().GetResult()但調用它們比調用ResultGetAwaiter().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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM