如何在使用模拟HttpMessageHandler时使用HttpClient管理Cookie [英] How to manage cookies with HttpClient when using a mocking HttpMessageHandler

查看:0
本文介绍了如何在使用模拟HttpMessageHandler时使用HttpClient管理Cookie的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个单元测试,它通过传入HttpRequestMessage个实例并接收回HttpResponseMessages个实例来调用类库。在这方面,它非常类似于测试WebApiApiController

我测试的代码将Cookie添加到HttpResponseMessage,并期望在后续传入的HttpRequestMessage调用中看到这些Cookie,这就是浏览器(或HttpWebRequest)的行为方式。

我没有使用HttpClientHandler,因为请求实际上并不在网络上,而是使用我用来初始化HttpClient的模拟HttpMessageHandler传递给产品。因此,HttpClientHandler中的cookie处理对我来说是不可访问的。似乎要获得我需要的Cookie行为,我必须手动解析HttpResponseMessage中的Cookie,然后手动将它们序列化到HttpRequestMessage。这也完全忽略了CookieContainer将Cookie正确应用于正确请求的逻辑。

有没有更简单的方法?

推荐答案

我自己编写了DelegatingHandler,它为我管理Cookie。我还在CookieContainer上编写了几个扩展方法,以便可以轻松地与HttpRequestMessageHttpResponseMessage一起使用:

internal class DangerouslySimpleCookieContainer : DelegatingHandler {
    internal DangerouslySimpleCookieContainer(CookieContainer cookieContainer = null) {
        this.Container = cookieContainer ?? new CookieContainer();
    }

    internal DangerouslySimpleCookieContainer(HttpMessageHandler innerHandler, CookieContainer cookieContainer = null)
        : base(innerHandler) {
        this.Container = cookieContainer ?? new CookieContainer();
    }

    public CookieContainer Container { get; set; }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
        this.Container.ApplyCookies(request);
        var response = await base.SendAsync(request, cancellationToken);
        this.Container.SetCookies(response);
        return response;
    }
}

internal static class CookieContainerExtensions {
    internal static void SetCookies(this CookieContainer container, HttpResponseMessage response, Uri requestUri = null) {
        Requires.NotNull(container, "container");
        Requires.NotNull(response, "response");

        IEnumerable<string> cookieHeaders;
        if (response.Headers.TryGetValues("Set-Cookie", out cookieHeaders)) {
            foreach (string cookie in cookieHeaders) {
                container.SetCookies(requestUri ?? response.RequestMessage.RequestUri, cookie);
            }
        }
    }

    internal static void ApplyCookies(this CookieContainer container, HttpRequestMessage request) {
        Requires.NotNull(container, "container");
        Requires.NotNull(request, "request");

        string cookieHeader = container.GetCookieHeader(request.RequestUri);
        if (!string.IsNullOrEmpty(cookieHeader)) {
            request.Headers.TryAddWithoutValidation("Cookie", cookieHeader);
        }
    }
}

这篇关于如何在使用模拟HttpMessageHandler时使用HttpClient管理Cookie的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆