簡體   English   中英

如何將 HttpContext.Request/Response 的標頭與 HttpRequestMessage.Request/Response 的標頭進行比較?

[英]How do I compare headers from HttpContext.Request/Response with those of HttpRequestMessage.Request/Response?

我對HttpContext class 使用與HttpRequestMessageHttpResponseMessage不同的請求和響應類型感到惱火。 HttpContext class 使用IHeaderDictionary作為標頭,而其他類使用HttpRequestHeadersHttpResponseHeaders作為標頭。 (兩者都派生自HttpHeaders 。)
我的問題是我正在處理 Web API 需要從上下文中提取標頭並在使用HttpClient.SendAsync(...)調用另一個站點時向前傳遞這些標頭。 (是的,網站!不是其他服務!)
我想要的是一個簡單的 function,它可以將標頭從上下文請求復制到新請求。 在執行請求后,我想使用相同的 function將響應中的標頭復制到我的上下文響應中。 這無法完成,因為標題是不同的類型。

涉及的類型有:
interface IHeaderDictionary: IDictionary<string, StringValues>{}
class HttpHeaders: IEnumerable<KeyValuePair<string, IEnumerable<string>>>
所以挑戰在於我們有一個帶有StringValues值的字典與一個帶有可枚舉 as 值的可枚舉。 比較蘋果和梨,基本上...
那么我如何制作一個可以將標題從一個列表分配給另一個列表的 function呢?

我能想到的最好的事情是部分 DRY,並且大部分是類型安全的。

void Copy<T, U>(IEnumerable<KeyValuePair<string, T>> from, IEnumerable<KeyValuePair<string, U>> to)
    where T : IEnumerable<string>
    where U : IEnumerable<string>
{
    if (to is IHeaderDictionary headerDictionary)
        foreach (var x in from)
            headerDictionary.Add(x.Key, new StringValues(x.Value.ToArray()));
    else
    if (to is HttpHeaders httpHeaders)
        foreach (var x in from)
            httpHeaders.Add(x.Key, new List<string?>(x.Value));
}

此方法假定 collections 實際上已經存在。 如果您必須創建目標集合並返回它,該方法將變得更加復雜,並且您將失去在調用站點推斷類型參數的能力。

為了證明代碼實際上可以編譯,我創建了一個 controller,它帶有一個采用可為空參數的Copy變體。 (這只是為了將所有內容保存在一個地方)。

[ApiController]
public class WeatherForecastController : ControllerBase
{
    void Copy<T, U>(IEnumerable<KeyValuePair<string, T>>? from, IEnumerable<KeyValuePair<string, U>>? to)
        where T : IEnumerable<string>
        where U : IEnumerable<string>
    {
        if (from == null || to == null)
            return;

        if (to is IHeaderDictionary headerDictionary)
            foreach (var x in from)
                headerDictionary.Add(x.Key, new StringValues(x.Value.ToArray()));
        else
        if (to is HttpHeaders httpHeaders)
            foreach (var x in from)
                httpHeaders.Add(x.Key, new List<string?>(x.Value));
    }

    public void Test()
    {
        // in real life, these come from somewhere else and won't be null
        HttpRequestHeaders? requestHeaders = null;
        HttpRequestHeaders? responseHeaders = null;

        // actual types are inferred. yay!
        Copy(HttpContext.Request.Headers, requestHeaders);
        Copy(requestHeaders, HttpContext.Request.Headers);
        Copy(HttpContext.Response.Headers, responseHeaders);
        Copy(responseHeaders, HttpContext.Response.Headers);
        Copy(requestHeaders, responseHeaders);
        Copy(responseHeaders, requestHeaders);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM