通过 HttpClient 的 HTTP Post 的 UrlEncode 非字符串属性
Posted
技术标签:
【中文标题】通过 HttpClient 的 HTTP Post 的 UrlEncode 非字符串属性【英文标题】:UrlEncode non-string properties for HTTP Post through HttpClient 【发布时间】:2017-01-12 18:18:57 【问题描述】:这段代码在python中
dataParams = urllib.urlencode(
"name": "myname",
"id": 2,
)
dataReq = urllib2.Request('mylink', dataParams)
dataRes = urllib2.urlopen(dataReq)
现在我正在尝试将其转换为 C#。直到现在我只能这样做
var dataParams = new FormUrlEncodedContent(
new KeyValuePair<string, string>[]
new KeyValuePair<string, string>("name", myname"),
new KeyValuePair<string, string>("id", "2"),
);
httpResponse = await httpClient.PostAsync(new Uri(dataString),dataParams);
httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
但我的问题是发布内容,因为发布数据需要同时是 int 和字符串。但我只能使用 FormUrlEncodedContent 以字符串格式发送数据。那么如何发送带有适当参数的发布请求。
【问题讨论】:
【参考方案1】:我不确定post data needs to be both int and string
是什么意思,因为application/x-www-form-urlencoded 基本上是一个带有字符串键值对的字符串。
因此,您的原始id
参数是字符串"2"
还是数字2
都没有关系。
它将被编码为相同的:name=mynameValue&id=2
所以您的代码没有任何问题。只需对原始 int
值使用 ToString
方法即可获取其字符串表示形式:
var id = 2;
var dataParams = new FormUrlEncodedContent(
new KeyValuePair<string, string>[]
new KeyValuePair<string, string>("name", myname"),
new KeyValuePair<string, string>("id", id.ToString()),
);
你可以用更少的样板来对复杂类型进行 urlencode,它甚至看起来更像原始的 python 代码:
public static class HttpUrlEncode
public static FormUrlEncodedContent Encode(Object obj)
if (obj == null)
throw new ArgumentNullException("obj");
var props = obj
.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.ToDictionary(
prop =>
prop.Name,
prop =>
(prop.GetValue(obj, null) ?? String.Empty).ToString());
return new FormUrlEncodedContent(props);
var dataParams = HttpUrlEncode.Encode(
new
name = "myname",
id = 2
);
【讨论】:
第二种方法到底如何不起作用?我已经用简单的[HttpPost] public ActionResult TestPost( String name, Int32 id)
进行了尝试,并且该操作接收到正确的数据。
不,我的意思是说我尝试了第一个并且它有效,所以我没有尝试第二个。 :)【参考方案2】:
如果您不介意小型库依赖项,Flurl [披露:我是作者] 会像您的 Python 示例一样简短明了,也许更是如此:
var dataParams = new
name: "myname",
id: 2
;
var result = await "http://api.com".PostUrlEncodedAsync(dataParams).ReceiveString();
【讨论】:
感谢您的回答,目前它对我有用,下次我一定会尝试您的图书馆。【参考方案3】:如果您的数据将包含数字和字符串值,您可以使用KeyValuePair<string,object>
,它应该接受您的任何数据。所以你的代码可能是:
var contentString = JsonConvert.SerializeObject(
new KeyValuePair<string, object>[]
new KeyValuePair<string, object>("name", "myname"),
new KeyValuePair<string, object>("id", 2),
);
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "URI")
Content = new StringContent(contentString)
;
httpResponse = await httpClient.SendAsync(requestMessage);
【讨论】:
我在FormUrlEncodedContent
上没有看到任何接受IEnumerable<string, object>
的constructors。并且单个现有构造函数 (msdn.microsoft.com/en-us/library/…) 不会接受这样的参数。
@EugenePodskal 你说得对,我想它必须是JsonConvert.SerializeObject
,我会相应地进行编辑。
不,他需要标准的application/x-www-form-urlencoded 编码。
这个答案不正确。 OP 询问是否发布 URL 编码的内容,而不是 JSON 内容。以上是关于通过 HttpClient 的 HTTP Post 的 UrlEncode 非字符串属性的主要内容,如果未能解决你的问题,请参考以下文章
如何通过python twisted HTTPClient生成POST和GET请求?
如何通过 HttpClient 在 POST 请求中将 JSON 数据作为正文发送