首页 > 解决方案 > 仅用于路径的 Uri Builder

问题描述

我偶然发现了 C# 中的 UriBuilder,它使代码更具可读性,而不是使用字符串插值或连接多个部分。例如,我可以执行以下操作:

var uriBuilder = new UriBuilder("https://github.com/dotnet/aspnetcore/search");
var parameters = HttpUtility.ParseQueryString(string.Empty);
parameters["q"] = "utf-8";
uriBuilder.Query = parameters.ToString();

这会给我 url https://github.com/dotnet/aspnetcore/search?q=utf-8。这在处理多个查询参数时变得特别方便。但是,有一个限制。它只允许我构建 url,但我只需要路径 + 查询参数。所以我想只以/dotnet/aspnetcore/search?q=utf-8字符串插值或连接之外的一些奇特方式构建部分。

让我解释一下为什么我需要这个。在我的服务部分,我有以下代码:

services.AddHttpClient("GitHub", client =>
{
    client.BaseAddress = new Uri("https://github.com/);
});

现在我可以在一些服务类中做到这一点:

private readonly HttpClient _httpClient;

public RequestService(IHttpClientFactory httpClientFactory)
{
    _httpClient = httpClientFactory.CreateClient("GitHub");
}

当我发送请求时,基地址已经设置好了,我只需要定义路径和 url 参数。到目前为止,除了使用字符串插值之外,我还没有找到更好的方法,这可能不是最好的方法。

public void SendRequest() {
    var request = new HttpRequestMessage(HttpMethod.Get,
        $"dotnet/aspnetcore/search?q={someString}");

    var response = await client.SendAsync(request);
}

标签: c#httpclient

解决方案


为了正确初始化包含其查询参数的路径,您可以使用内置QueryHelpersAddQueryString扩展方法(docs):

public void SendRequest() {
    Dictionary<string, string> queryString = new Dictionary<string, string>
    {
        { "q", "utf-8" }
    };
    string methodName = "dotnet/aspnetcore/search";
    methodName = QueryHelpers.AddQueryString(methodName, queryString);
    //methodName is "dotnet/aspnetcore/search?q=utf-8"

    var request = new HttpRequestMessage(HttpMethod.Get, methodName);
    var response = await this._httpClient.SendAsync(request);
}

不要忘记添加一个using Microsoft.AspNetCore.WebUtilities;.

额外的一点,HttpRequestMessage有两个参数化构造函数:

public HttpRequestMessage(HttpMethod method, string requestUri);
public HttpRequestMessage(HttpMethod method, Uri requestUri)

为了使用第二个构造函数,您可以轻松使用:

Uri uri = new Uri(methodName, UriKind.Relative);
var request = new HttpRequestMessage(HttpMethod.Get, uri);

推荐阅读