如果我想使用System.Net.HttpClient提交一个http获取请求,似乎没有api来添加参数,这是正确的吗?

是否有任何简单的api可用来构建查询字符串,不涉及构建名称值集合和url编码,然后最后连接它们? 我希望使用类似RestSharp的api(即AddParameter(..))


当前回答

对于那些不想包括系统。Web在项目中还没有使用它,你可以使用System.Net.Http的FormUrlEncodedContent,并做如下的事情:

keyvaluepair版本

string query;
using(var content = new FormUrlEncodedContent(new KeyValuePair<string, string>[]{
    new KeyValuePair<string, string>("ham", "Glazed?"),
    new KeyValuePair<string, string>("x-men", "Wolverine + Logan"),
    new KeyValuePair<string, string>("Time", DateTime.UtcNow.ToString()),
})) {
    query = content.ReadAsStringAsync().Result;
}

字典的版本

string query;
using(var content = new FormUrlEncodedContent(new Dictionary<string, string>()
{
    { "ham", "Glaced?"},
    { "x-men", "Wolverine + Logan"},
    { "Time", DateTime.UtcNow.ToString() },
})) {
    query = content.ReadAsStringAsync().Result;
}

其他回答

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;

希望它对你有用。

我正在开发的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);

与罗斯托夫的帖子一样,如果你不想包含对系统的引用。在你的项目中,你可以使用System.Net.Http.Formatting中的FormDataCollection,然后做如下的事情:

使用System.Net.Http.Formatting.FormDataCollection

var parameters = new Dictionary<string, string>()
{
    { "ham", "Glaced?" },
    { "x-men", "Wolverine + Logan" },
    { "Time", DateTime.UtcNow.ToString() },
}; 
var query = new FormDataCollection(parameters).ReadAsNameValueCollection().ToString();

我的答案与公认的答案/其他答案在全球范围内并无不同。我只是尝试为Uri类型创建一个扩展方法,它接受可变数量的参数。

public static class UriExtensions
{
    public static Uri AddParameter(this Uri url, params (string Name, string Value)[] @params)
    {
        if (!@params.Any())
        {
            return url;
        }

        UriBuilder uriBuilder = new(url);

        NameValueCollection query = HttpUtility.ParseQueryString(uriBuilder.Query);

        foreach (var param in @params)
        {
            query[param.Name] = param.Value.Trim();
        }

        uriBuilder.Query = query.ToString();

        return uriBuilder.Uri;
    }
}

使用的例子:

var uri = new Uri("http://someuri.com")
    .AddParameter(
       ("p1.name", "p1.value"),
       ("p2.name", "p2.value"),
       ("p3.name", "p3.value"));

或者简单地使用我的Uri扩展

Code

public static Uri AttachParameters(this Uri uri, NameValueCollection parameters)
{
    var stringBuilder = new StringBuilder();
    string str = "?";
    for (int index = 0; index < parameters.Count; ++index)
    {
        stringBuilder.Append(str + parameters.AllKeys[index] + "=" + parameters[index]);
        str = "&";
    }
    return new Uri(uri + stringBuilder.ToString());
}

使用

Uri uri = new Uri("http://www.example.com/index.php").AttachParameters(new NameValueCollection
                                                                           {
                                                                               {"Bill", "Gates"},
                                                                               {"Steve", "Jobs"}
                                                                           });

结果

http://www.example.com/index.php?Bill=Gates&Steve=Jobs