4

I have some code in different places where I have a Dictionary<string,string> containing parameters that needs to go on the query string. I've got some of my own code for formatting this so that it can be added to the end of the URL. Is there something built into this library that will do this for me?

3
  • 1
    possible duplicate of Build query string for System.Net.HttpClient get Commented Oct 16, 2013 at 22:29
  • 1
    I'm not quite sure I understand what you mean, but don't the following do what you want? HttpUtility.UrlEncode OR Uri.EscapeUriString. Commented Oct 16, 2013 at 22:33
  • @chuex I didn't mark my code as code which messed up the question. I have a dictionary and thought HttpClient might offer a method to convert this into a query string. I think the duplicate question link might be what I want. Commented Oct 16, 2013 at 22:39

1 Answer 1

9

You might want to consider using UriTemplates to construct Uris. The syntax is specified in RFC6570. I wrote a library that has a nuget package here.

With UriTemplates you can not only fill in query parameters like,

    [Fact]
    public void ShouldAllowUriTemplateWithQueryParamsWithOneValue()
    {
        var template = new UriTemplate("http://example.org/foo{?bar,baz}");
        template.SetParameter("baz", "yo");


        var uriString = template.Resolve();
        Assert.Equal("http://example.org/foo?baz=yo", uriString);
    }

Don't worry if you don't supply a query string parameter, the token will be removed.

It also handles path parameters,

    [Fact]
    public void ShouldAllowUriTemplateWithMultiplePathSegmentParameter()
    {
        var template = new UriTemplate("http://example.org/foo/{bar}/baz/{blar}");
        template.SetParameter("bar", "yo");
        template.SetParameter("blar", "yuck");
        var uriString = template.Resolve();
        Assert.Equal("http://example.org/foo/yo/baz/yuck", uriString);
    }

and some really nifty stuff with parameters that are lists and dictionaries,

    [Fact]
    public void ShouldAllowListAndSingleValueInQueryParam()
    {
        var template = new UriTemplate("http://example.org{/id*}{?fields,token}");
        template.SetParameter("id", new List<string>() { "person", "albums" });
        template.SetParameter("fields", new List<string>() { "id", "name", "picture" });
        template.SetParameter("token", "12345");
        var uriString = template.Resolve();
        Assert.Equal("http://example.org/person/albums?fields=id,name,picture&token=12345", uriString);
    }

and it will handle all sorts of tricky URI encoding issues,

    [Fact]
    public void ShouldHandleUriEncoding()
    {
        var template = new UriTemplate("http://example.org/sparql{?query}");
        template.SetParameter("query", "PREFIX dc: <http://purl.org/dc/elements/1.1/> SELECT ?book ?who WHERE { ?book dc:creator ?who }");
        var uriString = template.Resolve();
        Assert.Equal("http://example.org/sparql?query=PREFIX%20dc%3A%20%3Chttp%3A%2F%2Fpurl.org%2Fdc%2Felements%2F1.1%2F%3E%20SELECT%20%3Fbook%20%3Fwho%20WHERE%20%7B%20%3Fbook%20dc%3Acreator%20%3Fwho%20%7D", uriString);
    }


    [Fact]
    public void ShouldHandleEncodingAParameterThatIsAUriWithAUriParameter()
    {
        var template = new UriTemplate("http://example.org/go{?uri}");
        template.SetParameter("uri", "http://example.org/?uri=http%3A%2F%2Fexample.org%2F");
        var uriString = template.Resolve();
        Assert.Equal("http://example.org/go?uri=http%3A%2F%2Fexample.org%2F%3Furi%3Dhttp%253A%252F%252Fexample.org%252F", uriString);
    }

The only item that still is not working is encoding double byte Unicode characters in URIs. There is also a preview release that is PCL library allow you to use it in WinRT and on Windows Phone.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.