是否有将对象序列化为 HTTP 内容类型 "application/x-www-form-urlencoded" 的实用程序?
Is there a utility to serialise an object as HTTP content type "application/x-www-form-urlencoded"?
我以前从来没有这样做过,因为它一直只是我 post 编辑为该内容类型的实际形式,但最近我不得不 post 三个变量就像那样,我求助于 &
和 =
:
的肮脏连接
var content = new StringContent("grant_type=password&username=" + username + "&password=" + password.ToClearString(), Encoding.UTF8,
"application/x-www-form-urlencoded");
我确信必须有一个实用方法可以做到这一点,并且做得更好,并带有任何必要的编码。那会是什么?
您应该能够为此使用字符串插值。类似于:
var content = new StringContent($"grant_type=password&username={username}&password={password}", Encoding.UTF8, "application/x-www-form-urlencoded");
或者将其包装在 helper/factory 方法中:
public static class StringContentFactory
{
public static StringContent Build(string username, string password)
{
return new StringContent($"grant_type=password&username={username}&password={password}", Encoding.UTF8, "application/x-www-form-urlencoded");
}
}
使用反射获取 属性 名称和值,然后使用它们创建 System.Net.Http.FormUrlEncodedContent
public static class FormUrlEncodedContentExtension {
public static FormUrlEncodedContent ToFormUrlEncodedContent(this object obj) {
var nameValueCollection = obj.GetType()
.GetProperties()
.ToDictionary(p => p.Name, p => (p.GetValue(obj) ?? "").ToString());
var content = new FormUrlEncodedContent(nameValueCollection);
return content;
}
}
从那里调用对象的扩展方法将其转换为 FormUrlEncodedContent
是一件简单的事情
var model = new MyModel {
grant_type = "...",
username = "...",
password = "..."
};
var content = model.ToFormUrlEncodedContent();
如果这是一个 POCO 并且只使用 Newtonsoft 库,您也可以使用它:
public static class FormUrlEncodedContentExtension
{
public static FormUrlEncodedContent ToFormUrlEncodedContent(this object obj)
{
var json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
var keyValues = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
var content = new FormUrlEncodedContent(keyValues);
return content;
}
}
示例用法为:
var myObject = new MyObject {Grant_Type = "TypeA", Username = "Hello", Password = "World"};
var request = new HttpRequestMessage(HttpMethod.Post, "/path/to/post/to")
{
Content = myObject.ToFormUrlEncodedContent()
};
var client = new HttpClient {BaseAddress = new Uri("http://www.mywebsite.com")};
var response = await client.SendAsync(request);
我以前从来没有这样做过,因为它一直只是我 post 编辑为该内容类型的实际形式,但最近我不得不 post 三个变量就像那样,我求助于 &
和 =
:
var content = new StringContent("grant_type=password&username=" + username + "&password=" + password.ToClearString(), Encoding.UTF8,
"application/x-www-form-urlencoded");
我确信必须有一个实用方法可以做到这一点,并且做得更好,并带有任何必要的编码。那会是什么?
您应该能够为此使用字符串插值。类似于:
var content = new StringContent($"grant_type=password&username={username}&password={password}", Encoding.UTF8, "application/x-www-form-urlencoded");
或者将其包装在 helper/factory 方法中:
public static class StringContentFactory
{
public static StringContent Build(string username, string password)
{
return new StringContent($"grant_type=password&username={username}&password={password}", Encoding.UTF8, "application/x-www-form-urlencoded");
}
}
使用反射获取 属性 名称和值,然后使用它们创建 System.Net.Http.FormUrlEncodedContent
public static class FormUrlEncodedContentExtension {
public static FormUrlEncodedContent ToFormUrlEncodedContent(this object obj) {
var nameValueCollection = obj.GetType()
.GetProperties()
.ToDictionary(p => p.Name, p => (p.GetValue(obj) ?? "").ToString());
var content = new FormUrlEncodedContent(nameValueCollection);
return content;
}
}
从那里调用对象的扩展方法将其转换为 FormUrlEncodedContent
var model = new MyModel {
grant_type = "...",
username = "...",
password = "..."
};
var content = model.ToFormUrlEncodedContent();
如果这是一个 POCO 并且只使用 Newtonsoft 库,您也可以使用它:
public static class FormUrlEncodedContentExtension
{
public static FormUrlEncodedContent ToFormUrlEncodedContent(this object obj)
{
var json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
var keyValues = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
var content = new FormUrlEncodedContent(keyValues);
return content;
}
}
示例用法为:
var myObject = new MyObject {Grant_Type = "TypeA", Username = "Hello", Password = "World"};
var request = new HttpRequestMessage(HttpMethod.Post, "/path/to/post/to")
{
Content = myObject.ToFormUrlEncodedContent()
};
var client = new HttpClient {BaseAddress = new Uri("http://www.mywebsite.com")};
var response = await client.SendAsync(request);