简体   繁体   中英

HttpResponseMessage is always null running on android.(Works in WP8)

I'm new to this forum and to have a question about await/async use in Xamarin (Also the first time I work with). I am working for my internship on a project using Xamarin, PCL, MvvmCross. In my PCL im do a postrequest to a WCF service to login in my application. In WP8 everything just works fine, but when I am running my application on Android the response is always null.

Below you can find my httpclient class. The method with the post is 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

}
}

Regarding the website of Xamarin async/await is supported, but I did not find any similar problems. I hope you can help me.

I have solved my problem.

In Android, when you add the NuGet package with the HTTP Libraries, something went wrong when adding the references. You have to add the references mannualy to solve it. I also editted my Uri, now it works with the IP-address in the Uri.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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