Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How-to workaround differences with Uri and encoded URLs in .Net4.0 vs .Net4.5 using HttpClient

Uri behaves differently in .Net4.0 vs .Net4.5

var u = new Uri("http://localhost:5984/mycouchtests_pri/test%2F1");
Console.WriteLine(u.OriginalString);
Console.WriteLine(u.AbsoluteUri);

Outcome NET4.0

http://localhost:5984/mycouchtests_pri/test%2F1
http://localhost:5984/mycouchtests_pri/test/1

Outcome NET4.5

http://localhost:5984/mycouchtests_pri/test%2F1
http://localhost:5984/mycouchtests_pri/test%2F1

So when using the HttpClient distributed by Microsoft via NuGet requests like the above fail with .Net4.0, since the HttpRequestMessage is using the Uri.

Any ideas for a workaround?

EDIT There is a NON APPLICABLE workaround by adding configuration for <uri> in e.g. App.config or Machine.config (http://msdn.microsoft.com/en-us/library/ee656539(v=vs.110).aspx).

<configuration>
  <uri>
    <schemeSettings>
      <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes"/>
    </schemeSettings>
  </uri>
</configuration>

But as this is a tools library, that's not really an option. If the HttpClient for .Net4.0 is supposed to be on par with the one in .Net4.5, they should have the same behavior.

like image 891
Daniel Avatar asked Oct 11 '14 14:10

Daniel


1 Answers

Mike Hadlow wrote a blog post on this a few years back. Here's the code he came up with to get round this:

private void LeaveDotsAndSlashesEscaped()
{
    var getSyntaxMethod = 
        typeof (UriParser).GetMethod("GetSyntax", BindingFlags.Static | BindingFlags.NonPublic);
    if (getSyntaxMethod == null)
    {
        throw new MissingMethodException("UriParser", "GetSyntax");
    }

    var uriParser = getSyntaxMethod.Invoke(null, new object[] { "http" });

    var setUpdatableFlagsMethod = 
        uriParser.GetType().GetMethod("SetUpdatableFlags", BindingFlags.Instance | BindingFlags.NonPublic);
    if (setUpdatableFlagsMethod == null)
    {
        throw new MissingMethodException("UriParser", "SetUpdatableFlags");
    }

    setUpdatableFlagsMethod.Invoke(uriParser, new object[] {0});
}

I think it just sets the flag that's available from .config in code, so while it's hacky, it's not exactly unsupported.

like image 133
Mark Rendle Avatar answered Oct 04 '22 04:10

Mark Rendle