When working with URLs in our applications, there are times when they may become too long, clunky, unreadable, and difficult to use. In such situations, we can employ a URL shortener to make them shorter, more readable, and easier to share. Essentially, a URL shortener takes our long URLs and provides a shorter URL that, when clicked, redirects our users to the original long URL. In this article, let’s discuss the steps required to build a custom URL shortener for our applications with .NET.
Let’s dive in.
Why Do We Need to Shorten Our URLs?
There are many cases where shortening our URLs can prove useful. Let’s quickly look at some of those. Firstly, as mentioned in our introduction, when our URLs become too long, they become unreadable and difficult to share. Therefore, one reason why we might want to shorten our URLs is to make them easy to read and share.
Also, imagine a scenario where we manually type a long URL, for example, one with over fifty characters. Such a process would be tedious, error-prone, and time-consuming, as we would have to be careful not to mix up the characters. Shortening our URL to fewer characters can prove very useful in such circumstances. It makes our typing task simpler, less error-prone, and faster.
Furthermore, long URLs are susceptible to breaking when we copy them from one medium and paste them into another. With short URLs, we can prevent potential link breakages from occurring.
How Will Our URL Shortener Work?
Now that we have seen some reasons for shortening our URLs, let’s discuss how our URL shortener will work.
To build our URL shortener, we will utilize an ASP.NET Core Web API to receive and handle user requests. The web API will receive long URLs via a POST
request and then generate a short unique code for it. To store this shortcode and the long URL it points to, we will utilize an in-memory dictionary. When we append this shortcode to our base URL we get the shortened URL.
Subsequently, when users send a GET
request to the shortened URL, we can then use the shortcode to retrieve its corresponding long URL from the dictionary.
We should note that our URL shortener app will only support creating and retrieving URLs. We won’t add functionalities for deleting or updating the shortened URLs.
Build Our URL Shortener
Next up, let’s implement the URL shortener. We will carry out this implementation in two parts. First, we will create our service class. Then, we’ll add the web API controllers.
Create the Service Class
Our service class will have two methods – one for retrieving a shortcode when we pass a long URL to it and another for retrieving a long URL via a shortcode.
Before we define these methods, let’s first create the class and add some helper members to it:
public class UrlShortenerService : IUrlShortenerService { private static readonly char[] _chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray(); private Dictionary<string, string> UrlDict { get; set; } = []; private static string GenerateShortCode() { return string.Create(5, _chars, (shortCode, charsState) => Random.Shared.GetItems(charsState, shortCode)); } }
These initial members play a crucial part in our URL shortener service.
Our first readonly field, _chars
, gives us a set of alphanumeric characters that we will combine randomly to get a unique code for a long URL.
Next, we define the dictionary that will serve as the database for our application. Finally, we create the GenerateShortCode()
method that will create a shortcode of 5
characters for any long URL we wish to shorten.
With that, we can now implement the service methods.
Create URL Shortener Methods
First, let’s define a GetShortCode()
method:
public string GetShortCode(string longUrl) { foreach (var pair in UrlDict) { if (pair.Value == longUrl) { return pair.Key; } } string shortCode; while (true) { shortCode = GenerateShortCode(); if (UrlDict.TryAdd(shortCode, longUrl)) { break; } } return shortCode; }
Here, we first check if a URL already has a shortcode in our database. If it does, we simply return it.
Otherwise, we create one for it in the while
loop using the GenerateShortCode()
method and then add it to our dictionary. In the rare scenario where the shortcode we create already exists in the dictionary, we execute this loop more than once. We run the loop until we have successfully added a shortcode and its main URL to the dictionary.
Next, let’s implement a GetLongUrl()
method:
public string? GetLongUrl(string shortCode) { if (UrlDict.TryGetValue(shortCode, out string? longUrl)) { return longUrl; } return default; }
For this method, we invoke the TryGetValue()
method to retrieve the long URL for a specific shortcode. If the shortcode exists in our database, we retrieve its value and return it. Otherwise, we return the default value for strings.
Now, for us to use this service we just defined in our controller, we have to add it to the Dependency Injection(DI) container in our Program
class:
builder.Services.AddSingleton<IUrlShortenerService, UrlShortenerService>();
Here, we register our service as a singleton, which means that we will create and use only one instance of this service throughout the lifetime of our app.
Create the URL Shortener API Endpoint
Now, with our service class ready for use, let’s add a controller to our project, injecting our IUrlShortenerService
interface:
[Route("api/[controller]")] [ApiController] public class URLShortenerController(IUrlShortenerService urlShortenerService) : ControllerBase { }
Next, let’s add an action method for shortening URLs to this controller:
[HttpPost("/createshorturl")] public IActionResult ShortenUrl([FromBody] string longUrl) { if (!Uri.TryCreate(longUrl, UriKind.Absolute, out _)) { return BadRequest("This is not a valid URL"); } return Ok(urlShortenerService.GetShortCode(longUrl)); }
We use the TryCreate()
method to check if the long URL our user provided is valid. If it is, we shorten it and return the shortcode in the response body. But if it isn’t, we return a 400 BadRequest error.
With that, let’s add an action method that will return the main URL when a user provides a shortened URL:
[HttpGet("/{shortCode}")] public IActionResult GetLongUrl(string shortCode) { var longUrl = urlShortenerService.GetLongUrl(shortCode); if (longUrl is null) { return NotFound(); } return Ok(longUrl); }
In this method, we call the GetLongUrl()
service method to retrieve the corresponding long URL. If we successfully get the URL, we redirect our user to it. Otherwise, we return a 404 NotFound response.
Finally, let’s add a third method that we will use to check if we have shortened a URL correctly and that the shortened URL points to the correct long URL:
[HttpGet("/samplepage")] public IActionResult GetSamplePage() { return Ok("This is a sample page to test our URL shortener."); }
Great! Our controller is now complete.
With this controller, we will handle all incoming URL shortening requests from our users, call the necessary service methods to shorten the URLs, and return unique shortcodes to our users. Additionally, if a user visits a shortened URL address, we will retrieve and return the original URL to them.
Test the URL Shortener
Now, it’s time to check if the functionalities in our application are working.
First, let’s try to shorten an internal URL. Let’s add the https://localhost:7075/samplepage
URL as the body of the POST
https://localhost:7075/createshorturl
request and check the result:
IRAHq
Next, let’s use this code to access the original URL. We can do this by requesting the https://localhost:7075/IRAHq
endpoint:
https://localhost:7075/samplepage
Here, we get the original URL as the body of the response.
With that, let’s test our app with an external URL. For this, let’s use https://code-maze.com/
, the CodeMaze homepage:
6kzyi
Again, let’s test this with our shortcode endpoint to check if this shortcode and its main URL exist in our database:
https://code-maze.com/
Again, we get the long URL we shortened.
So, that’s it. Our URL shortener works as expected.
Conclusion
In this article, we have explored how to build a URL shortener in .NET.
First, we discussed some reasons for shortening URLs and then described how a URL shortener operates. After that, we created a custom URL shortener using the ASP.NET Core Web API framework.
Finally, we used Postman to test this URL shortener and saw that it functions perfectly.