在HttpWebRequest中设置“ Content-Type”标头的最佳方法?

时间:2019-06-04 20:01:42

标签: c# .net reflection

在我的程序中,我基于以下JSON模式生成自定义HttpWebRequest

{
    "Endpoint": "String",
    "Method": "String",
    "Headers": [
       {
           "Name": "String",
           "Value": "String"
       }
    ]
}

下面的代码循环遍历每个Header并将其添加到HttpWebRequest

var request = (HttpWebRequest)WebRequest.Create(Endpoint);
foreach (var item in Headers)
{
    request.Headers.Add(item.Name, item.Value);
}

这适用于大多数自定义标头,但是我遇到了设置ContentType标头的问题。由于无法通过上述方法添加特定的标头,因此我设计了一种方法,使用Reflection来设置request的{​​{1}}属性。

ContentType

我的问题是:使用public static void SetHeaderValue(this HttpWebRequest request, string headerName, string headerValue) { Type type = typeof(HttpWebRequest); PropertyInfo prop = type.GetProperty(headerName); if (prop != null) { prop.SetValue(request, headerValue); } } 是解决此问题的最佳方法,还是解决该问题的安全方法?

2 个答案:

答案 0 :(得分:1)

使用反射可以为您提供最紧凑的代码。但这绝对不是最快,也可能不是最直观的方式。显式列出所有标准标头并使用属性设置器填充它们也许很有意义:

var request = (HttpWebRequest)WebRequest.Create(Endpoint);
foreach (var item in Headers)
{
    string headerName = item.Name.ToLower();
    switch (headerName)
    {
        case "contenttype": request.ContentType = item.Value; break;
        case "accept": request.Accept = item.Value; break;
        case "useragent": request.UserAgent = item.Value; break;
        // ... other standard headers
        default:
            // set custom header as usual
            request.Headers.Add(item.Name, item.Value);
            break;
    }
}

答案 1 :(得分:1)

反射听起来像是一个坏主意,它很脆弱(有点,他们可能不会改变内部结构),但是您正在反对设计。 我一直认为隐藏“特殊”价值的设计是错误的

我会去看地图或上面的开关。如果需要测试,可以插入地图。

// textarea code, might not compile

var request = (HttpWebRequest)WebRequest.Create(Endpoint);
var special = new Dictionary<string, Action<string>>{
    ["contenttype"] = v => request.ContentType = v,
    ["accept"] = v => request.Accept = v,
    ["useragent"] = v => request.UserAgent = v,
};
foreach (var item in Headers)
{
    special.TryGetValue(item.Name.ToLower(), out var fn) ?
        fn(item.Value) :
        request.Headers.Add(item.Name, item.Value);
}