1

我将数据发布到要求我提交重复的查询字符串键的服务(丑陋且未在任何标准中指定)。

我正在使用 WebClient 对象来构建请求。我想继续使用它,因为它在项目的其他地方经常使用。

当我这样做时

 foreach(var f in formats)                
      client.QueryString.Add("formats", f);

我得到一个&formats=format_1,format_2,format_3服务不支持的列表。

有没有比这种老式的丑陋更好的选择:

var extraQueryString = string.Empty;

extraQueryString += "?apiKey=" + TRANSCODE_KEY;
extraQueryString += "&fileKey=" + fileKey;

foreach (var f in formats)     
      extraQueryString += "&formats=" + f;

var response = client.UploadData(TRANSCODE_URI + "task" + extraQueryString , new byte[] { });
4

2 回答 2

1

这样做的原因是因为NameValueCollection用逗号分隔重复的键。您可以扩展NameValueCollection并覆盖该Get方法并让它返回您想要的格式。

public class DupeNVC: NameValueCollection
{
    private string _duplicateKey;
    public DupeNVC(string duplicateKey = null)
    {
        _duplicateKey = duplicateKey;
    }

    public override string Get(int index)
    {
        //check if duplicate key has been specified
        //if not, then call the default Get implementation
        if (!String.IsNullOrEmpty(_duplicateKey))
        {
            ArrayList list = (ArrayList)base.BaseGet(index);              

            int num = (list != null) ? list.Count : 0;
            if (num == 1)
            {
                return (string)list[0];
            }
            if (num > 1)
            {
                StringBuilder stringBuilder = new StringBuilder((string)list[0]);

                for (int i = 1; i < num; i++)
                {
                    //format our string and append the duplicate key specified
                    stringBuilder.AppendFormat("&{0}=", _duplicateKey);
                    stringBuilder.Append((string)list[i]);
                }
                return stringBuilder.ToString();                   
            }
            return null;
        }
        else
           return base.Get(index);
    }

} 

你可以NameValueCollection像平常一样使用它,但是如果你在构造函数中传入一个重复的字符串,它会寻找那个重复的键并运行上面修改过的代码(否则它将只使用默认base.Get方法。

DupeNVC dnvc = new DupeNVC("formats");

foreach(var f in formats)     
    dnvc.Add("formats", f);

webClient.QueryString = dnvc;

这尚未经过全面测试,但它应该输出您想要的查询字符串格式。当然,这可以通过收集重复键进一步扩展,但这只是为了让您了解当前问题。

于 2013-07-02T00:45:41.787 回答
0

这是我对此的看法。WebClient 本质上与此类的 ToString 方法类似;它获取所有键,然后一次检索一个值,进行连接。所以我重写了 AllKeys 以返回一个包含重复元素的数组..

例如,如果特定键具有多个值:

nvc["hello"] = { "a", "b", "c" }

然后我的 AllKeys 将返回一个带有“hello”的数组 3 次。WebClient 会天真地请求它 3 次。字典跟踪请求“hello”的次数,每次返回不同的(伪枚举器)

public class ParrotingNameValueCollection : NameValueCollection
{

    Dictionary<string, int> _indexTracker = new Dictionary<string, int>();

    public override string[] AllKeys
    {
        get
        {
            var l = new List<string>();
            foreach (var k in base.AllKeys)
            {
                foreach (var x in (ArrayList)base.BaseGet(k))
                    l.Add(k);

                _indexTracker[k] = 0;
            }
            
            return l.ToArray();
        }
    }


    public override string Get(string name)
    {

        var list = (ArrayList)base.BaseGet(name);

        var toReturn = (string)list[_indexTracker[name]];

        _indexTracker[name]++;

        return toReturn;
    }

    public override string ToString()
    {
        string delimiter = String.Empty;
        StringBuilder values = new StringBuilder();
        foreach (string name in this.AllKeys)
        {
            values.Append(delimiter);
            values.Append((name));
            values.Append("=");
            values.Append((this[name]));
            delimiter = "&";
        }

        return values.ToString();
    }
}
于 2020-11-20T00:04:55.770 回答