Tom el Safadi
Tom el Safadi

Reputation: 6786

Uri Builder for Path only

I stumbled across the UriBuilder in C# that makes the code a little bit more readable instead of using string interpolation or concatenating multiple parts. For example I could do the following:

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

Which would give me the url https://github.com/dotnet/aspnetcore/search?q=utf-8. This becomes especially handy, when dealing with multiple query parameters. However, there is a limitation. It only alows me to build urls but I need it for only the path + query parameters. So I would like to build only the portion /dotnet/aspnetcore/search?q=utf-8 in some fancy way other than string interpolation or concatenation.

Let me explain you why I need this. In my services section, I have the following code:

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

And now I can just do this in some service class:

private readonly HttpClient _httpClient;

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

When I send a request, the base address will already be set and I only need to define the path and the url parameters. Until now I haven't find a better way other than using string interpolation, which is a probably not the nicest way of doing.

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

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

Upvotes: 3

Views: 3185

Answers (1)

Shahar Shokrani
Shahar Shokrani

Reputation: 8762

In order to properly init the path to includes its query params you can use the built-in QueryHelpers's AddQueryString extension methods (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);
}

Do not forget to add a using Microsoft.AspNetCore.WebUtilities;.

A little extra, the HttpRequestMessage has two parameterize constructors:

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

In order to work with the second constructor, you can easily use:

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

Upvotes: 2

Related Questions