如何将FormUrlEncodedContent用于复杂的数据类型? [英] How do I use FormUrlEncodedContent for complex data types?

查看:65
本文介绍了如何将FormUrlEncodedContent用于复杂的数据类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要与仅接受表单编码的有效载荷的第三方端点进行交互.终结点需要在此终结点上使用复杂的数据类型,这意味着类似这样的内容(但采用表单编码,而不是JSON):

I need to interact with a third party endpoint that only accepts form encoded payloads. The endpoint wants complex data types at this endpoint, meaning something like this (but form encoded, not JSON):

{
    "foo": "bar",
    "baz": {
        "zip": "zap"
    }
}

我在Google搜索和该端点的文档中指出,该编码应采用以下形式:

My googling and the docs for the endpoint indicates that this should be form encoded like this:

foo=bar&baz[zip]=zap

我正在使用 HttpClient ,并且我想使用 FormUrlEncodedContent ,但是当我这样做时,我的 [] 用转义字符替换了.

I am using HttpClient and I want to use FormUrlEncodedContent but when I do it is replacing my [] with escaped characters.

public class Tests
{
    [Fact]
    public void Test()
    {
        var content = new Dictionary<String, String>
        {
            { "foo", "bar" },
            { "baz[zip]", "zap" }
        };
        var formContent = new FormUrlEncodedContent(content);
        Assert.Equal("foo=bar&baz[zip]=zap", formContent.ReadAsStringAsync().Result);
    }
}

我最终得到的是:

foo=bar&baz%5Bzip%5D=zap

推荐答案

您的问题有两个.第一:

There are two issues in your question. Number one:

我的Google搜索表明应采用以下形式进行编码:

My googling indicates that this should be form encoded like this:

foo=bar&baz[zip]=zap

不.没有将多维键值结构转换为单维结构的约定或标准.

No. There is no convention or standard that transforms a multi-dimension key-value structure into a single-dimension one.

如果您考虑一下,这样的转换将很快变得非常笨拙.对象语义比URL编码语义更具表现力.FWIW,即使很容易做到,他们甚至都无法就如何将纯数组编码为URL达成共识.

If you think about it, such a transformation will become very unwieldy very quickly. Object semantics are a lot more expressive than URL-encoding semantics. FWIW, they can't even agree on how to encode plain arrays into URLs, even though that would easily be possible.

由于没有标准,因此归结为建立服务器和客户端可以使用的约定.(*):

Since there is no standard, it comes down to setting up a convention that server and client can live with. The convention that would cause the least headache and the least chance for nasty bugs would be(*):

  • 将您的对象序列化为JSON.这给你一个字符串.
  • 将该字符串作为URL参数中的值进行传输.
  • 在接收端进行相反操作.

因此,在JS中,您可以这样做:

So in JS you would do:

encodeURIComponent(JSON.stringify({
    "foo": "bar",
    "baz": {
        "zip": "zap"
    }
}));

为您提供

"%7B%22foo%22%3A%22bar%22%2C%22baz%22%3A%7B%22zip%22%3A%22zap%22%7D%7D"

可以安全地将其作为URL参数进行传输,并以最小的努力进行处理.

This can be transferred safely as an URL parameter and processed with minimal effort.

对于.NET,您可以从几个序列化选项中进行选择,其中两个是DataContractJsonSerializer和JavaScriptSerializer,在此处讨论.

For .NET you can pick from several serialization options, two of them being the DataContractJsonSerializer and the JavaScriptSerializer, discussed over here.

强烈建议您不要为此任务使用自己的序列化方案.

I would strongly recommend against rolling your own serialization scheme for this task.

第二名:

但是,当我这样做时,它会将我的[]替换为转义字符.

but when I do it is replacing my [] with escaped characters.

当然.URL编码键值对中的键应遵循与值相同的规则.像 {"a& b":"c& d"} 这样的对将被编码为 a%26b = c%26d .实际上,您可以将其发送为%61%26%62 =%63%26%64 .换句话说,URL解码值但在接收端忘记了URL解码键名是一个错误.因此,忘记了URL- encoding 键名.在此处.

Of course. The keys in URL-encoded key-value pairs are subject to the same rules as the values. A pair like {"a&b": "c&d"} would be encoded as a%26b=c%26d. In fact, you could send it as %61%26%62=%63%26%64. In other words, URL-decoding values but forgetting about URL-decoding key names on the receiving end is a bug. So is forgetting about URL-encoding key names. A discussion about what characters can be used in what form in a URL is over here.

(*)缺少直接将数据作为 Content-Type:application/json 传输,这比将其压缩到查询字符串中更可取."

(*) Short of "transferring the data as Content-Type: application/json directly, which is preferable to squeezing it into a query string.

这篇关于如何将FormUrlEncodedContent用于复杂的数据类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆