4

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

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

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

有没有更简单的方法?

4

1 回答 1

6

我自己编写了一个DelegatingHandler为我管理 cookie 的程序。我还写了几个扩展方法,CookieContainer以便可以轻松地与HttpRequestMessageand一起使用HttpResponseMessage

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);
        }
    }
}
于 2013-03-23T16:01:50.293 回答