GetResponse() in C#

2019-04-09 11:35发布

问题:

I have the following code in my portable class library. But it gives error that

System.Net.HttpWebRequest does not contain a definition for GetResponse().

public async Task<object> GetStateByUserId(string userID)
    {
        HttpWebRequest request;
        Stream receiveStream;
        StreamReader readStream;

        request =(HttpWebRequest)CreateGetWebRequest("state/uid/"+userID);
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {

        receiveStream = response.GetResponseStream ();
        readStream = new StreamReader(receiveStream);
        string str = readStream.ReadToEnd().ToString();
        s = JsonConvert.DeserializeObject<state>(str);
            return s;
        }


    }

Anyone know why it is so?

回答1:

If you are writing for targetting the portable class library, you will have to use the asynchronous methods as GetResponse is not available.

Instead you have to use BeginGetReponse and EndGetResponse.

In your case, this could look like this:

public void StartRequest ()
{
    HttpWebRequest request = (HttpWebRequest)CreateGetWebRequest("state/uid/"+userID);
    request.BeginGetResponse(new AsyncCallback(FinishRequest), request);
}

private void FinishRequest (IAsyncResult result)
{
    HttpWebResponse response = (result.AsyncState as HttpWebRequest).EndGetResponse(result) as HttpWebResponse;

    Stream receiveStream = response.GetResponseStream();
    StreamReader readStream = new StreamReader(receiveStream);

    // ...
}

If you are using .NET 4.5, you can do it like this:

HttpWebRequest request = (HttpWebRequest)CreateGetWebRequest("state/uid/"+userID);
Task<HttpWebResponse> requestTask = Task.Factory.FromAsync<HttpWebResponse>(request.BeginGetResponse, request.EndGetResponse, request);
using (var response = await requestTask)
{
    Stream receiveStream = response.GetResponseStream();
    StreamReader readStream = new StreamReader(receiveStream);
}


回答2:

If you look at the documentation for GetResponse() and compare it with GetResponseAsync(), you'll notice that in Version information, for example Windows Store apps are missing for GetResponse() and other versions of the framework are missing in GetResponseAsync().

Depending on the versions of the framework you chose for your PCL, you might be able to use GetResponseAsync() directly (for example if you chose .Net 4.5 and Windows Store, but nothing else).

If you need some of the frameworks that don't support GetResponseAsync() out of the box, then I think the best solution here is to use the Microsoft.Bcl.Async NuGet package, which will allow you to use GetResponseAsync() in other versions of the framework.

Also, switching to GetResponseAsync() means you will need to use await to get the value, which also means making this method and all methods that call it async. (Though confusingly, it seems you already switched to async without using await, which doesn't make much sense.)