【问题标题】:HttpClient error in PCL filePCL 文件中的 HttpClient 错误
【发布时间】:2015-08-26 13:34:37
【问题描述】:

我刚刚在 VS 2013 中创建了一个 PCL 项目,并将以下 Nuget 包添加到我的项目中,并选择了所有可用平台,因为我想在 .NET 和我的 Xamarin 项目中重新使用它。

  • Microsoft HTTP 客户端库
  • Json.NET

但是在下面一行:

HttpResponseMessage response = await client.PostAsync(uri, content);

我收到以下错误:

Cannot await 
'System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage>'

在这一行:

return await response.Content.ReadAsStringAsync();

我收到以下错误:

Cannot await 'System.Threading.Tasks.Task<string>'

这是在我的通用应用程序的共享项目中正常工作的完整代码。

    public static async Task<string> PostDataAsync<T>(string uriString, 
    T data, ContentType contentType, bool isWrapped)
    {
        HttpClient client = new HttpClient();

        Uri uri = new Uri(uriString);

        string wrappedName = data.GetType().Name;
        string postData = string.Empty;
        string prefix = string.Empty;
        string suffix = string.Empty;

        if (contentType == ContentType.Xml)
        {
            //postData = SerializerHelper.SerializeObjectToXML<T>(data, 
            //true, true, true, false);
        }
        else
        {
            if (isWrapped)
            {
                prefix = string.Concat("{\"", data.GetType().Name, "\":");
                suffix = "}";
            }
            postData = prefix + JsonConvert.SerializeObject(data) + suffix;
        }

        client.DefaultRequestHeaders.Accept.Add(new 
        MediaTypeWithQualityHeaderValue(contentType == 
        ContentType.Json ? "application/json" : "application/xml"));

       client.DefaultRequestHeaders.Host = uri.Host;

        StringContent content = new StringContent(postData,
        System.Text.Encoding.UTF8, contentType ==
        ContentType.Json ? "application/json" : "application/xml");

        HttpResponseMessage response = await client.PostAsync(uri, content);

        if (response.StatusCode == HttpStatusCode.NotFound)
            throw new NetworkConnectivityException();
        else if (response.StatusCode != HttpStatusCode.OK)
            throw new Exception(response.RequestMessage.ToString());

        return await response.Content.ReadAsStringAsync();
    }

这些只是我读过的几篇文章,但都没有指出正确的解决方案:

我设法创建了一个工作函数,与上面的函数略有不同,但原理保持不变,但我不确定这是正确的方法,因为我正在“等待”在函数内而不是从调用它的应用程序中。有人可能只是想确认以下是否也可以?请注意,虽然它可以编译,但我还没有机会在 Xamarin 中尝试。

public static Task<U> PostDataAsync<T, U>(string baseAddress, string
requestUri, T data, ContentType contentType = ContentType.Json, 
bool isWrapped = true, double timeOut = 1200000)
    {
        string contentTypeString = (contentType ==
        ContentType.Json ? "json" : "xml");

        using (HttpClientHandler handler = new HttpClientHandler())
        {
            using (HttpClient client = new HttpClient(handler))
            {
                client.BaseAddress = new Uri(baseAddress);
                client.Timeout = TimeSpan.FromMilliseconds(timeOut);
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(
                    new MediaTypeWithQualityHeaderValue("application/" + 
                    contentTypeString));

                string postData = string.Empty;
                string prefix = string.Empty;
                string suffix = string.Empty;

                if (contentType == ContentType.Json)
                {
                    if (isWrapped)
                    {
                        prefix = string.Concat("{\"", 
                        data.GetType().Name, "\":");
                        suffix = "}";
                    }
                    postData = prefix + JsonConvert.
                    SerializeObject(data) + suffix;
                }
                else
                {

                }

                HttpRequestMessage request = new 
                HttpRequestMessage(HttpMethod.Post, requestUri);
                request.Content = new StringContent(postData,
                                                    Encoding.UTF8,
                                                    "application/" +
                contentTypeString);

                if (handler.SupportsTransferEncodingChunked())
                {
                    request.Headers.TransferEncodingChunked = true;
                }

                HttpResponseMessage response = null;
                string dataReturned = string.Empty;
                U dataObject = default(U);

                Task resp = client.SendAsync(request)
                      .ContinueWith(responseTask =>
                      {
                          response = responseTask.Result;
                          if (responseTask.Result.IsSuccessStatusCode)
                          {
                              Task<string> dataTask = 
                              response.Content.ReadAsStringAsync();

                              dataReturned = dataTask.Result.ToString();
                              dataObject = JsonConvert.
                              DeserializeObject<U>(FixJson
                               (dataReturned, "Result"));
                          }
                          else
                          {
                              dataReturned = "HTTP Status: " +
                              response.StatusCode.ToString() + 
                              " - Reason: " + response.ReasonPhrase;
                          }
                      });

                resp.Wait();

                return Task.Factory.StartNew(() => dataObject);
            }
        }
    }

有什么想法可以解决我的第一个函数的问题吗?第二个功能可以吗?

谢谢。

【问题讨论】:

    标签: c# .net xamarin async-await portable-class-library


    【解决方案1】:

    安装 NuGet 包 Microsoft.Bcl.Async 以获得对 asyncawait 的支持。

    【讨论】:

    • 我在 .NET 4.5 中还需要这个吗?我以为只有 .NET 4 或更低版本才需要这样做?
    • 这确实是一直以来的问题!!不明白为什么当解决方案选择 Silverlight 或 WP 作为支持平台的一部分时,它们没有自动包含在内!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-14
    • 2023-03-14
    • 2018-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多