HttpResponseMessage在android上始终为null。(在WP8中工作)

时间:2013-11-21 10:16:40

标签: c# xamarin.android json.net async-await dotnet-httpclient

我是这个论坛的新手,并且对Xamarin中的等待/异步使用有疑问(这也是我第一次使用)。 我正在为使用Xamarin,PCL,MvvmCross的项目实习。 在我的PCL中,我会对WCF服务进行postrequest以登录我的应用程序。在WP8中,一切正常,但是当我在Android上运行我的应用程序时,响应始终为空。

您可以在下面找到我的httpclient类。帖子的方法是InternalPostAsync

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using Anton.Mobile.Shared.Infrastructure;
using System.Net;
using Newtonsoft.Json.Linq;
using System.Net.Http.Headers;

namespace Anton.Mobile.Shared.Data
{
public class AntonClient
{
    #region static

    /// <summary>
    /// Base Uri of the Ria service (e.g. http://example.com/)
    /// </summary>
    private static readonly Uri _baseUri = new Uri(Config.BaseUri);

    /// <summary>
    /// Last cookie response header (Session, authentication, ...)
    /// </summary>
    private static string _cookieHeader = null;

    /// <summary>
    /// Lock object for read/write <para>_cookieHeader</para>
    /// </summary>
    private static object _lockObj = new object();

    #endregion

    #region protected

    /// <summary>
    /// Creates a client
    /// </summary>
    /// <param name="container">Cookie container to use</param>
    /// <returns>HttpClient</returns>
    protected virtual HttpClient CreateClient(CookieContainer container)
    {
        //set container on handler for tracking cookies between request-response
        var handler = new HttpClientHandler()
        {
            CookieContainer = container,
            UseCookies = true,
            UseDefaultCredentials = false,
        };

        //Create client and set the base address
        var cl = new HttpClient(handler)
        {
            BaseAddress = _baseUri
        };

        if (!string.IsNullOrEmpty(_cookieHeader))
        {
            cl.DefaultRequestHeaders.Add("Cookies", _cookieHeader);
        }
        return cl;
    }


    /// <summary>
    /// Creates a JSON content request
    /// </summary>
    /// <param name="jsonContent">JSON value</param>
    /// <returns>JSON content</returns>
    protected virtual HttpContent CreateRequestContent(string jsonContent)
    {
        var content = new StringContent(jsonContent,Encoding.UTF8,"application/json");
        //content.Headers.Add("ContentType", "application/json");

        return content;
    }

    /// <summary>
    /// Save cookies <para>_cookieHeader</para>
    /// </summary>
    /// <param name="container">cookie container</param>
    protected void ParseCookies(HttpResponseMessage msg)
    {
        IEnumerable<string> values;
        if (!msg.Headers.TryGetValues("Set-Cookie", out values) || !values.Any())
            return;


        //var cookies = container.GetCookieHeader(_baseUri);

        var cs = new List<string>();
        foreach (var v in values)
        {
            string[] vs = v.Split(new char[] { ';' });
            string[] value = vs[0].Split(new char[] { '=' });
            container.Add(new Uri("Http://initesting"), new Cookie(value[0], value[1]));
            cs.Add(string.Format("{0}={1}", value[0], value[1]));
        }
        lock (_lockObj)
        {
            _cookieHeader = string.Join(";", cs.ToArray());
        }
    }

    private static CookieContainer container = new CookieContainer();

    /// <summary>
    /// Create a new cookie container from <para>_cookieHeaders</para>
    /// </summary>
    /// <returns>Cookie container</returns>
    protected CookieContainer CreateCookieContainer()
    {

        //lock (_lockObj)
        //{
        //    if (!string.IsNullOrEmpty(_cookieHeader))
        //    {
        //        foreach (var header in _cookieHeader.Split(new char[] { ';' }))
        //        {
        //            container.SetCookies(_baseUri, header);
        //        }
        //    }
        //}
        return container;
    }

    /// <summary>
    /// Executes a POST HTTP Request
    /// </summary>
    /// <param name="jsonContent">POST JSON content</param>
    /// <param name="uri">Service uri</param>
    /// <returns>Response content as string (JSON)</returns>
    protected virtual async Task<string> InternalPostAsync(string jsonContent, Uri uri)
    {
        var container = CreateCookieContainer();
        using (var client = CreateClient(container))
        {
            var content = CreateRequestContent(jsonContent);
            var response = await client.PostAsync(uri, content);

            if (response.StatusCode != HttpStatusCode.OK)
            {
                return null; //todo
            }

            ParseCookies(response);

            return await response.Content.ReadAsStringAsync();
        }
    }

    /// <summary>
    /// Executes a GET HTTP Request
    /// </summary>
    /// <param name="uri">Service uri</param>
    /// <returns>Response content as string (JSON)</returns>
    protected virtual async Task<string> InternalRequestAsync(Uri uri)
    {
        var container = CreateCookieContainer();


        using (var client = CreateClient(container))
        {
            HttpResponseMessage response = await client.GetAsync(uri);

            if (response.StatusCode != HttpStatusCode.OK)
            {
                return null;
            }
            ParseCookies(response);
            return await response.Content.ReadAsStringAsync();
        }
    }

    #endregion protected

    #region public



    /// <summary>
    /// Executes a POST HTTP Request for a given Request key
    /// </summary>
    /// <typeparam name="TRequest">Request Type</typeparam>
    /// <typeparam name="TResult">Result Type</typeparam>
    /// <param name="request">Request POST value to JSON serializing</param>
    /// <param name="key">Unique Request Key</param>
    /// <returns>Deserialized POST response content of type TResult</returns>
    public async Task<TResult> PostAsync<TRequest, TResult>(TRequest request, RequestKey key)
        where TRequest : class
        where TResult : class
    {
        try
        {
            var uri = RequestMap.GetUri(key);
            string jsonResult = await InternalPostAsync(request.SerializeJson(), uri);
            return jsonResult.DeserializeJson<TResult>();
        }
        catch (Exception)
        {
            //todo
        }
        return default(TResult);
    }

    /// <summary>
    /// Executes a POST HTTP Request for a given service uri
    /// </summary>
    /// <typeparam name="TRequest">Request Type</typeparam>
    /// <param name="request">Request POST value to JSON serializing</param>
    /// <param name="uri">Service URI</param>
    /// <returns>Deserialized POST response content of type dynamic</returns>
    public async Task<dynamic> PostAsync<TRequest>(TRequest request, string uri)
    {
        try
        {
            string jsonResult = await InternalPostAsync(request.SerializeJson(), new Uri(uri, UriKind.Absolute));
            return jsonResult.DynamicJson();
        }
        catch (Exception)
        {
            //todo
        }
        return null;
    }

    /// <summary>
    /// Executes a GET HTTP Request for a givin key and query string parameter info
    /// </summary>
    /// <typeparam name="TResponse">Response Type</typeparam>
    /// <param name="key">Unique request key</param>
    /// <param name="queryString">Querystring info</param>
    /// <returns>Deserialized POST response content of type TResult</returns>
    public async Task<TResponse> RequestAsync<TResponse>(RequestKey key, IDictionary<string, string> queryString = null)
    {
        try
        {
            string jsonResult = await InternalRequestAsync(RequestMap.GetUri(key, queryString));
            var dynamicResult = jsonResult.DynamicJson();
            var item = (dynamicResult as JObject)[RequestMap.GetValue(key) + "Result"]["RootResults"].First; //todo: better solution for this
            return item.ToObject<TResponse>();
        }
        catch (Exception)
        {
            //todo
        }
        return default(TResponse);
    }

    #endregion public

}
}

关于支持Xamarin async / await的网站,但我没有发现任何类似的问题。我希望你能帮助我。

1 个答案:

答案 0 :(得分:0)

我已经解决了我的问题。

在Android中,当您使用HTTP库添加NuGet包时,添加引用时出错了。您必须添加mannualy参考来解决它。我还编辑了我的Uri,现在它与Uri中的IP地址一起工作。