繁体   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