如果我想使用System.Net.HttpClient提交一个http获取请求,似乎没有api来添加参数,这是正确的吗?
是否有任何简单的api可用来构建查询字符串,不涉及构建名称值集合和url编码,然后最后连接它们? 我希望使用类似RestSharp的api(即AddParameter(..))
如果我想使用System.Net.HttpClient提交一个http获取请求,似乎没有api来添加参数,这是正确的吗?
是否有任何简单的api可用来构建查询字符串,不涉及构建名称值集合和url编码,然后最后连接它们? 我希望使用类似RestSharp的api(即AddParameter(..))
当前回答
您可能想看看Flurl[披露:我是作者],这是一个流畅的URL构建器,带有可选的配套库,可以将其扩展为一个成熟的REST客户机。
var result = await "https://api.com"
// basic URL building:
.AppendPathSegment("endpoint")
.SetQueryParams(new {
api_key = ConfigurationManager.AppSettings["SomeApiKey"],
max_results = 20,
q = "Don't worry, I'll get encoded!"
})
.SetQueryParams(myDictionary)
.SetQueryParam("q", "overwrite q!")
// extensions provided by Flurl.Http:
.WithOAuthBearerToken("token")
.GetJsonAsync<TResult>();
查看文档了解更多细节。完整的软件包在NuGet上可用:
PM>安装包Flurl。Http
或者只是独立的URL构建器:
PM>安装包Flurl
其他回答
HttpClient client = new HttpClient();
var uri = Environment.GetEnvironmentVariable("URL of Api");
var requesturi = QueryHelpers.AddQueryString(uri, "parameter_name",parameter_value);
client.BaseAddress = new Uri(requesturi);
然后你也可以添加请求头例如:
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("x-api-key", secretValue);
响应语法eg:
HttpResponseMessage response = client.GetAsync(requesturi).Result;
希望它对你有用。
如果我想使用System.Net.HttpClient提交一个http get请求 似乎没有API来添加参数,这是正确的吗?
Yes.
是否有任何简单的api可用来构建查询字符串 不涉及构建名称值集合和url编码 然后最后把它们连接起来?
肯定的:
var query = HttpUtility.ParseQueryString(string.Empty);
query["foo"] = "bar<>&-baz";
query["bar"] = "bazinga";
string queryString = query.ToString();
会给你预期的结果:
foo=bar%3c%3e%26-baz&bar=bazinga
你可能还会发现UriBuilder类很有用:
var builder = new UriBuilder("http://example.com");
builder.Port = -1;
var query = HttpUtility.ParseQueryString(builder.Query);
query["foo"] = "bar<>&-baz";
query["bar"] = "bazinga";
builder.Query = query.ToString();
string url = builder.ToString();
会给你预期的结果:
http://example.com/?foo=bar%3c%3e%26-baz&bar=bazinga
你可以非常安全地将它提供给HttpClient。GetAsync方法。
我找不到比创建一个扩展方法来将Dictionary转换为QueryStringFormat更好的解决方案。Waleed A.K.提出的解决方案也不错。
遵循我的解决方案:
创建扩展方法:
public static class DictionaryExt
{
public static string ToQueryString<TKey, TValue>(this Dictionary<TKey, TValue> dictionary)
{
return ToQueryString<TKey, TValue>(dictionary, "?");
}
public static string ToQueryString<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, string startupDelimiter)
{
string result = string.Empty;
foreach (var item in dictionary)
{
if (string.IsNullOrEmpty(result))
result += startupDelimiter; // "?";
else
result += "&";
result += string.Format("{0}={1}", item.Key, item.Value);
}
return result;
}
}
和他们:
var param = new Dictionary<string, string>
{
{ "param1", "value1" },
{ "param2", "value2" },
};
param.ToQueryString(); //By default will add (?) question mark at begining
//"?param1=value1¶m2=value2"
param.ToQueryString("&"); //Will add (&)
//"¶m1=value1¶m2=value2"
param.ToQueryString(""); //Won't add anything
//"param1=value1¶m2=value2"
我正在开发的RFC 6570 URI Template库能够执行此操作。所有编码都按照RFC为您处理。在撰写本文时,beta版本已经可用,它不是稳定的1.0版本的唯一原因是文档没有完全满足我的期望(参见问题#17、#18、#32、#43)。
你可以单独构建一个查询字符串:
UriTemplate template = new UriTemplate("{?params*}");
var parameters = new Dictionary<string, string>
{
{ "param1", "value1" },
{ "param2", "value2" },
};
Uri relativeUri = template.BindByName(parameters);
或者你可以构建一个完整的URI:
UriTemplate template = new UriTemplate("path/to/item{?params*}");
var parameters = new Dictionary<string, string>
{
{ "param1", "value1" },
{ "param2", "value2" },
};
Uri baseAddress = new Uri("http://www.example.com");
Uri relativeUri = template.BindByName(baseAddress, parameters);
由于我必须重用这几次,所以我提出了这个类,它只是帮助抽象查询字符串是如何组成的。
public class UriBuilderExt
{
private NameValueCollection collection;
private UriBuilder builder;
public UriBuilderExt(string uri)
{
builder = new UriBuilder(uri);
collection = System.Web.HttpUtility.ParseQueryString(string.Empty);
}
public void AddParameter(string key, string value) {
collection.Add(key, value);
}
public Uri Uri{
get
{
builder.Query = collection.ToString();
return builder.Uri;
}
}
}
使用将被简化成这样:
var builder = new UriBuilderExt("http://example.com/");
builder.AddParameter("foo", "bar<>&-baz");
builder.AddParameter("bar", "second");
var uri = builder.Uri;
将返回uri: http://example.com/?foo=bar%3c%3e%26-baz&bar=second