Search code examples
c#.nethttplistenerrequest

How to handle Url encoding in HttpListenerRequest?


I'm building a simple server that uses HttpListener to process requests. The query string parameters I send to it are url encoded if necessary. For example, to send the Kanji string "尺八", the encoding is "%E5%B0%BA%E5%85%AB".

My sample url, then is "/?q=%E5%B0%BA%E5%85%AB".

In my context callback, I have:

HttpListenerContext context = Listener.EndGetContext();
string rawUrl = context.Request.RawUrl;
string query = context.Request.QueryString["q"];

Checking the results, I get:

rawUrl = "/?q=%E5%B0%BA%E5%85%AB" 
query = "尺八"

But if I look at context.Request.Url, I get {http://localhost:8080/?q=尺八}.

It looks like the query string in context.Request.QueryString is being decoded using some encoding other than UTF-8.

My workaround is to ignore context.Request.QueryString and create my own by doing this:

var queryString = HttpUtility.ParseQueryString(context.Request.Url.Query);

That gives me the correct value, but it seems like something of a hack.

Is there any way to tell the HttpListener (or the context, or the request) to interpret the query string as UTF-8, which I think is the standard anyway? Or should I just live with this workaround?


Solution

  • By looking at the code, it relies on ContentEncoding being set to UTF8. Here is the snipit from the QueryString property of HttpListenerRequest:

    public NameValueCollection QueryString
    {
        get
        {
            NameValueCollection nvc = new NameValueCollection();
            Helpers.FillFromString(nvc, this.Url.Query, true, this.ContentEncoding);
            return nvc;
        }
    }
    

    Since there is no way to modify the ContentEncoding property your stuck with your 'hack'. Anyway, I think your use of HttpUtility.ParseQueryString is likely going to serve you the best.