将CookieContainer与NSUrlSessionHandler结合使用

时间:2018-07-04 14:13:47

标签: xamarin.ios

在Xamarin应用程序中,我试图从使用ModernHttpClient.NativeMessageHandler转到使用NSUrlSessionHandler,但是我遇到了使用CookieContainer我尝试过的代码的障碍写的是:

var httpHandler = new NSUrlSessionHandler();
httpHandler.AllowAutoRedirect = false;
httpHandler.CookieContainer = cookieContainer;

return new HttpClient(httpHandler);

由于NSUrlSessionHandler没有CookieContainer属性,因此无法编译。

在设置供处理程序使用的cookie时,是否有可能实现类似的目的?

2 个答案:

答案 0 :(得分:0)

HttpClientHandlerNSUrlSessionHandler都是HttpMessageHandler的子类,并实现SendAsync()方法。 CookieContainer是仅属于HttpClientHandler的构造,并且您发现NSUrlSessionHandler中不存在该构造。

在Xamarin.iOS中,您可以直接使用NSHttpCookieStore,这是一个具有与NSUrlSessionHandler自动共享的共享cookie存储的单例。您可以浏览NSHttpCookieStorage文档中的SetCookie方法。

示例:

{
    foreach (var cookie in NSHttpCookieStorage.SharedStorage.Cookies)
    {
       Console.WriteLine($"Name: {cookie.Name}, Path: {cookie.Path}"
    }
}

答案 1 :(得分:0)

我最终扩展了nsurlSessionHandler并实现了我的cookieLogic。

示例:

using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Autofac;
using Foundation;
using Appname.Mobile;
using Appname.Mobile.Services;

namespace Appname.Mobile.iOS
{
    [Preserve]
    public class CustomMessageHandler : NSUrlSessionHandler
    {
        static ICookieStorageService CookiesService { get; set; }
        static CookieContainer Container { get; set; }

        public KDSHttpClientHandler()
        {
            CookiesService = App.Container.Resolve<ICookieStorageService>();
        }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (CookiesService != null)
        {
            Container = CookiesService.GenerateCookieContainer(request.RequestUri);
            CookiesService.ApplyRecentCookie(Container, request);
        }

        var result = await base.SendAsync(request, cancellationToken);

        if (CookiesService != null)
        {
            var cookieHeaders = result.Headers.Where(h => h.Key.Equals("Set-Cookie", StringComparison.InvariantCultureIgnoreCase)).ToList();

            foreach (var header in cookieHeaders)
            {
                try
                {
                    if (header.Value != null)
                    {
                        var cookieParts = header.Value.First().Split(';');
                        var cookieValue = cookieParts[0].Split('=');
                        Container.Add(new Cookie(cookieValue[0], cookieValue[1], "/", request.RequestUri.GetBaseDomain()));
                        CookiesService.UpdateCookies(Container, request.RequestUri);
                    }
                }
                catch (Exception ex)
                {
                    App.Logger.Error("CustomMessageHandler.SendAsync.CookieContainer", ex.Message);
                }
            }
        }

        return result;
    }
}
}