简体   繁体   English

HttpResponseMessage 到字符串

[英]HttpResponseMessage to string

I am calling a method of which returns Task, in the calling method I need to read the response in form of string.我正在调用一个返回Task的方法,在调用方法中我需要以字符串的形式读取响应。

Here's the code that I have put:这是我放的代码:

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;
}

I expect string but this error is thrown:我期望字符串,但抛出此错误:

Cannot implicitly convert type 
'System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage>' to 
'System.Net.Http.HttpResponseMessage'

Your problem is at: 你的问题是:

HttpResponseMessage result=Validate(Uri,stringContent);

Validate is returning a task, not a HttpResponseMessage . Validate是返回任务,而不是HttpResponseMessage

Change that to: 改为:

var result = Validate(Uri,stringContent).Result;

Just to clean up the code a bit and avoid using Result if you can afford to change it like: 只是为了清理代码并避免使用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();
}

Be consistent with your coding style. 与您的编码风格保持一致。 As to why calling .Result is bad, as people are pointing out in the comments, check this blog . 至于为什么要调用.Result是坏的,正如人们在评论中指出的那样,请查看此博客

  1. Just for readability change the method name from Validate(..) to ValidateAsync(..) . 只是为了可读性,将方法名称从Validate(..)更改为ValidateAsync(..) Just to make clear that this method returns a task and you have to await it. 只是要明确这个方法返回一个任务,你必须等待它。

  2. You're missing an await when calling your Validate method. 在调用Validate方法时,您错过了等待。 If you do not want or can make the caller async then use the method GetAwaiter().GetResult() and you'll get what you want. 如果您不想或可以使调用者异步,那么使用方法GetAwaiter().GetResult() ,您将得到您想要的。

  3. Replace ReadAsStringAsync().Result with ReadAsStringAsync().GetAwaiter().GetResult() 替换ReadAsStringAsync().ResultReadAsStringAsync().GetAwaiter().GetResult()

Like others wrote in comments calling .Result is bad because it could cause locks. 像其他人一样在评论中写道.Result很糟糕,因为它可能导致锁定。 The same applies in general to GetAwaiter().GetResult() but calling them is preferred over calling Result . 这同样适用于GetAwaiter().GetResult()但调用它们比调用ResultGetAwaiter().GetResult() The best option is to use await/async . 最好的选择是使用await/async

When you want to know whats the difference between GetAwaiter().GetResult() vs calling Result you can read this: Is Task.Result the same as .GetAwaiter.GetResult()? 当你想知道GetAwaiter().GetResult() vs调用Result之间的区别时你可以读到: Task.Result与.GetAwaiter.GetResult()相同吗?

Method Validate returns the task and is asynchronous. 方法Validate返回任务并且是异步的。 Basically you can call this method in two different ways: 基本上你可以用两种不同的方式调用这个方法:

1) await the result of Validate in another async method, like this... 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) block current execution while waiting for this resul, like this... 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;
}

Choose the 1st way by default unless you really have an urge to block the calling thread. 默认选择第一种方式,除非你真的有阻止调用线程的冲动。

Note that when using 2nd solution in WinForms, WPF or ASP.NET apps you will probably have a deadlock. 请注意,在WinForms,WPF或ASP.NET应用程序中使用第二个解决方案时,您可能会遇到死锁。 modifying Validate method like this should solve the problem: 像这样修改Validate方法应该可以解决问题:

response = await client.PostAsync(baseUri,content).ConfigureAwait(false);

You can easyly write: var json = result.Content.ReadAsStringAsync().GetAwaiter().GetResult();您可以轻松编写: var json = result.Content.ReadAsStringAsync().GetAwaiter().GetResult();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM