C#: Using a Uri to percent encode data



  • So I've spent most of this week working with a partner organization who is having troubles sending data to our API. The API requires that the data be percent encoded according to RFC 3986 (in short, the usual % encoding of non-alphanumeric, - . _ ~, and UTF-8 encoding of non-ASCII characters).

    When they sent us a person's name that had all three of é, a space, and an apostrophe, it would be encoded wrong and cause our API to reject the request. I sent them an email to check their non alpha-numeric characters and make sure that the encoding was right. First they tested unicode characters and got back to me... nope those work. Then I explained that in Java, the URLEncoder makes spaces a + instead of %20, so check that too... nope, that works.

    Finally they get back to me and say it was the apostrophe. That seemed odd, as in my experience URL encoding libraries usually encode apostrophes too (Java, JS, Python off the top of my head). It turns out that their "fix" is to use this code in C#:

        foo = new Uri("Person's name");
        postData += foo.Query.Replace("'", "%27");
    

    When I see this, I figure that there must be a better way than passing data into a Uri class to be percent encoded, but I don't use C# regularly. I did some Googling and apparently this is what people do in C#? 1, 2, (or write their own encoder).

    I mean, why would it be a normal procedure to pass free-form data into a "URI" (which may be a theoretically valid URI) just so you can percent encode it? wtf





  • They dropped the ball. NET is usually good with crap like this.



  • @quijibo said:

    When I see this, I figure that there must be a better way than passing data into a Uri class to be percent encoded, but I don't use C# regularly. I did some Googling and apparently this is what people do in C#? 1, 2, (or write their own encoder).

    Huh?



  • I am sure this stuff has worked fine since the first versions of .NET.



  • In my limited experience working with .Net developers, they're usually so abstracted from all the raw web concepts that their knowledge is very limited regarding cookies, response codes, and everything defined in a RFC. On one hand this is good because MS did a great job at doing it, but on the other, if the developer is not motivated to learn about this stuff, you'll end up with code like the one above.



  • @quijibo said:

    I did some Googling and apparently this is what people do in C#? 1, 2, (or write their own encoder).

    No; it's in WebUtility.

    Anybody doing that shit is an idiot you should piss on.


  • Considered Harmful

    @blakeyrat said:

    No; it's in WebUtility.

    If it's using different logic between the two classes, then the framework is TRWTF.



  • @error said:

    If it's using different logic between the two classes, then the framework is TRWTF.

    Yeah well, nobody ever said the .net framework was perfect. It also throws an exception if a HTTP request comes back with a 4xx response. (A "404" isn't exceptional, you idiots, it's an entirely acceptable and normal thing for a server to return. 5xx responses we can argue about, but throwing exceptions for 4xx responses is definitely wrong.)



  • It also doesn't work properly with redirects. You can choose to follow redirects on a 3xx response, but if you do so, no state is updated during the redirect. Only after the final page is located does state get updated. Which means if you point at a page that redirects to a page that sets cookies before redirecting back to the original page, you're in for one hell of an infinite loop.

    The solution is to manually process cookies yourself in an event handler and manually issue the redirect. And because the relevant class is sealed, you have to attach this event handler (and set the relevant properties for it to fire) manually for each instance of it.


  • FoxDev

    or write a navigation extension method that chooses not to follow redirects so state gets updated and then follows the redirect until response < 300 or response >= 400

    extension methods FTW



  • @blakeyrat said:

    No; it's in WebUtility.

    As of .NET 4.5. Okay, clearly lots of people (including me) are out of date on their .NET skills... but it took Microsoft 10 years to figure that there should be a library to encode strings? crazy!

    Aside from that, the supposed "solution" that the other org sent to us is wrong, as it misses several characters, as mentioned in the links. Too bad it will take another week to drill that into them.



  • Maybe ASP.NET Webforms developers because that was designed to look like WinForms.



  • @quijibo said:

    As of .NET 4.5. Okay, clearly lots of people (including me) are out of date on their .NET skills... but it took Microsoft 10 years to figure that there should be a library to encode strings? crazy!

    It just got renamed. It used to be HttpUtility. http://msdn.microsoft.com/en-us/library/system.web.httputility(v=vs.80).aspx



  • Which was in the Stackoverflow link, in my earlier response.



  • Congratulations?



  • Thankyou how gracious.


Log in to reply