【问题标题】:Best way to set "Content-Type" header in HttpWebRequest?在 HttpWebRequest 中设置“Content-Type”标头的最佳方法?
【发布时间】:2019-06-04 20:01:42
【问题描述】:

在我的程序中,我根据以下 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 来设置requestContentType 属性。

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);
    }
}

我的问题是:使用Reflection 是解决此问题的最佳方法,还是解决此问题的安全方法?

【问题讨论】:

标签: c# .net reflection


【解决方案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;
    }
}

【讨论】:

    【解决方案2】:

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

    我会选择地图或开关。如果需要测试,可以注入地图。

    // 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);
    }
    

    【讨论】:

    • 这也是一种选择。但首先你忘记了new关键字,其次你会得到一个KeyNotFoundException:最好使用special.ContainsKey(item.Name.ToLower())之类的东西
    • @RomanKoliada , new 不见了,ContainsKey 不如TryGetValue 所以我修好了。
    猜你喜欢
    • 2015-05-05
    • 1970-01-01
    • 2012-11-02
    • 2022-10-15
    • 2013-12-10
    • 2019-04-19
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多