Click here to Skip to main content
15,880,725 members
Articles / Programming Languages / Visual Basic
Tip/Trick

Better URL Building with Flurl

Rate me:
Please Sign up or sign in to vote.
4.84/5 (20 votes)
19 Jun 2018CPOL3 min read 38.2K   27   9
An introduction to Flurl, an open-source .NET library for fluently building URLs

Introduction

If you build a lot of URLs in .NET, you've probably found that it can be get a bit cumbersome. You start with basic string building. But even with proper use of String.Format, dealing optional parameters and URL encoding still gets messy quickly. You can't help but think there must be a better way.

At some point, you discover UriBuilder and think all your problems are solved. But you quickly realize that while UriBuilder is great for assembling the bits on the left side of the URL (host, port, scheme, etc.), it offers little help on the right side (path segments and query string), and that's where all the variability tends to be. You find that most of the time you're starting with a config setting or fixed constant representing some "base" URL, and regress back to string-building to construct the rest.

Sound familiar? Maybe you've rolled your own library to address some of these gaps. If not, you might want to check out Flurl. Flurl is a tiny library that sets out to solve these problems with as little "noise" as possible.

Show Me Some Code!

Here's what Flurl looks like:

JavaScript
using Flurl;

var url = "http://www.some-api.com"
    .AppendPathSegments("path", "to", "endpoint")
    .SetQueryParams(new {
        api_key = ConfigurationManager.AppSettings["SomeApiKey"],
        max_results = 20,
        q = "Don't worry, I'll get encoded!"
    });

If extension methods, fluent APIs, and anonymous objects are not your cup of tea, Flurl supports a more traditional style that gives you the same results:

C#
Url url = new Url("http://www.some-api.com");
url.AppendPathSegment("endpoint");
url.QueryParams["api_key"] = ConfigurationManager.AppSettings["SomeApiKey"];
url.QueryParams["max_results"] = 20;
url.QueryParams["q"] = "Don't worry, I'll get encoded!";

There's also a singular version of AppendPathSegments and SetQueryParams:

JavaScript
url.AppendPathSegment("one").SetQueryParam("x", 5);

SetQueryParam(s) overwrites existing values of the same name:

JavaScript
"http://mysite.com".SetQueryParams(new { x = 1, y = 2 }).SetQueryParam("y", 3);
// result: http://mysite.com?x=1&y=3

In some rare cases, you might actually want the same key specified multiple times in the query string. Pass an array of values to achieve this:

JavaScript
"http://mysite.com".SetQueryParam("x", new[] { 1, 2 });
// result: http://mysite.com?x=1&x=2

When a null value is passed to SetQueryParam(s), the key/value pair is excluded entirely. This behavior can be leveraged to help cut down on messy conditional logic.

JavaScript
"http://mysite.com".SetQueryParams(new { x = 1, y = null, z = 3 });
// result: http://mysite.com?x=1&z=3

A URL object converts back to a string implicitly. You can use ToString() explicitly if you prefer, but the compiler won't complain if you don't:

JavaScript
Response.Redirect(url);

Flurl can also be used to parse an existing URL, again focusing on the "right side":

JavaScript
var url = new Url("http://site.com/some/long/path?x=1&y=2");
var path = url.Path; // contains "http://site.com/some/long/path"
var query = url.QueryParams; // an IDictionary<string, object> containing x and y
var root = Url.GetRoot(url); // contains "http://site.com"

How often do you forget whether that "BaseURL" app setting already contains a trailing slash? Wish there was an equivalent to Path.Combine for URLs so you don't need to worry about it? Flurl gives you one:

JavaScript
var url = Url.Combine("http://foo.com/", "/too/", "/many/", "/slashes", "too", "few");
// result: http://foo.com/too/many/slashes/too/few

AppendPathSegment has the same behavior with respect to ensuring there is one and only one separator between segments.

Encoding

Flurl takes care of encoding characters in URLs but takes a different approach with path segments than it does with query string values. The assumption is that query string values are highly variable (such as from user input), whereas path segments tend to be more "fixed" and may already be encoded, in which case you don't want to double-encode. Here are the rules Flurl follows:

  • Query string values are fully URL-encoded.
  • For path segments, reserved characters such as / and % are not encoded.
  • For path segments, illegal characters such as spaces are encoded.
  • For path segments, the ? character is encoded, since query strings get special treatment.

Portability

Flurl is a portable class library, meaning you can use it in your Xamarin, Silverlight, and Windows Phone apps just as easily as applications targeting the "full" .NET framework.

Where Do I Get it?

Flurl is freely available on NuGet:

PM> Install-Package Flurl 

Flurl.Http

There are many reasons you might need to build URLs. For me, it's mostly for the purpose of calling RESTful APIs. I built Flurl.Http as companion library that allows you to seamlessly call the URL along the same fluent chain that you build it. It covers a lot of the same territory as other HTTP client libraries like RestSharp. I plan to cover Flurl.Http in depth in a future article, but for now you can check out the main website for details.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionJust What I Was Looking For... Pin
Hyland Computer Systems21-Jun-18 7:45
Hyland Computer Systems21-Jun-18 7:45 
QuestionNice article Pin
Member 1380375619-Jun-18 23:18
Member 1380375619-Jun-18 23:18 
GeneralMy vote of 5 Pin
LightTempler19-Jun-18 9:41
LightTempler19-Jun-18 9:41 
QuestionNice library! :) Pin
FreeRider122-Mar-17 9:41
FreeRider122-Mar-17 9:41 
SuggestionSee the constructed URL Pin
wvd_vegt23-Mar-16 4:27
professionalwvd_vegt23-Mar-16 4:27 
GeneralRe: See the constructed URL Pin
R. Hoffmann26-Jun-18 5:04
professionalR. Hoffmann26-Jun-18 5:04 
The .ToString() method has been overridden to supply the full URL, including the query string.
QuestionMy vote of 5 Pin
Austin Mullins10-Feb-15 11:45
Austin Mullins10-Feb-15 11:45 
GeneralMy vote of 5 Pin
Spencer Kittleson10-Feb-15 10:12
professionalSpencer Kittleson10-Feb-15 10:12 
GeneralMy vote of 5 Pin
PapyRef10-Feb-15 4:49
professionalPapyRef10-Feb-15 4:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.