Search code examples
c#httprequest

Why is HttpRequestMessage decoding my encoded string


I am trying to make a Http request, like the following:

var category = Uri.EscapeDataString("Power Tools");

var request = new HttpRequestMessage(HttpMethod.Get, $"/api/Items/GetAll?category={category}");

category now equals: Power%20Tools

The request gets translated to:

request = {Method: GET, RequestUri: 'http://localhost/api/Items/GetAll?category=Power Tools', ...

Why is HttpRequestMessage decoding my encoded string?


Solution

  • I reproduce in Console app in .NET 5. I think, it's just the ToString that decode the url to be friendly on debug information. I don't find a information to this on the documentation, but .NET is now open source.

    Generaly, the method ToString is used to generate debug information. See See the source code of HttpRequestMessage.ToString :

    public override string ToString()
    {
        StringBuilder sb = new StringBuilder();
    
        sb.Append("Method: ");
        sb.Append(method);
    
        sb.Append(", RequestUri: '");
        sb.Append(requestUri == null ? "<null>" : requestUri.ToString());
        ...
        return sb.ToString();
    }
    

    This just display requsetUri.ToString() and requestUri is type of Uri. From the official documentation of Uri.String:

    The unescaped canonical representation of the Uri instance. All characters are unescaped except #, ?, and %.

    // Create a new Uri from a string address.
    Uri uriAddress = new Uri("HTTP://www.Contoso.com:80/thick%20and%20thin.htm");
    
    // Write the new Uri to the console and note the difference in the two values.
    // ToString() gives the canonical version.  OriginalString gives the orginal
    // string that was passed to the constructor.
    
    // The following outputs "http://www.contoso.com/thick and thin.htm".
    Console.WriteLine(uriAddress.ToString());
    
    // The following outputs "HTTP://www.Contoso.com:80/thick%20and%20thin.htm".
    Console.WriteLine(uriAddress.OriginalString);