[英]How do I compare headers from HttpContext.Request/Response with those of HttpRequestMessage.Request/Response?
我對HttpContext
class 使用與HttpRequestMessage
和HttpResponseMessage
不同的請求和響應類型感到惱火。 HttpContext class 使用IHeaderDictionary
作為標頭,而其他類使用HttpRequestHeaders
和HttpResponseHeaders
作為標頭。 (兩者都派生自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.