.NET 7 Url Shortener
In this article we will be creating a Minimal API Url Shortener app.
You can watch the full video on youtube
Let us get started first we need to create project
dotnet new webapi -minimal -n UrlShortner
Lets do some clean up and will get the following program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.Run();
We need to install some package to utilise SQLite
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet add package Microsoft.EntityFrameworkCore.Design
first we need to add the connection string, inside our app settings let us add the following
"ConnectionStrings": {
"DefaultConnection": "DataSource=app.db;"
}
Now we need to add our data model which will represent the url in our database
using Microsoft.AspNetCore.WebUtilities;
namespace UrlShortner.Models;
public class ShortUrl
{
public int Id { get; set; }
public string Url { get; set; }
public string UrlChunk { get; set; }
}
Now we need to add the Url DTO
namespace UrlShortner.Models;
public class UrlDto
{
public string Url { get; set; }
}
Next the return url dto
namespace UrlShortner.Models;
public class ShortUrlDto
{
public string Url { get; set; }
}
Let us create our db context
class ApiDbContext : DbContext
{
public virtual DbSet<ShortUrl> Urls {get;set;}
public ApiDbContext(DbContextOptions<ApiDbContext> options) : base(options){ }
}
Next we need to inject our connection string in our application, and setup the DbContext
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApiDbContext>(options =>
options.UseSqlite(connectionString));
Now let us add the migration files, and then create the database
dotnet ef migrations add "initial migration"
dotnet ef database update
The next step is we need to add the post
app.MapPost("/shortenUrl", async (UrlDto item, ApiDbContext db, HttpContext context) =>
{
if (!Uri.TryCreate(item.Url, UriKind.Absolute, out var inputUri))
return Results.BadRequest("Invalid Url");
var random = new Random();
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var randomSte = new string(Enumerable.Repeat(chars, 7)
.Select(s => s[random.Next(s.Length)]).ToArray());
var sUrl = new ShortUrl()
{
Url = inputUri.ToString(),
UrlChunk = randomSte
};
db.Urls.Add(sUrl);
await db.SaveChangesAsync();
var result = $"{context.Request.Scheme}://{context.Request.Host}/{sUrl.UrlChunk}";
return Results.Ok(new ShortUrlDto
{
Url = result
});
});
Now let us handle the redirection functionality
app.MapFallback(async (ApiDbContext db, HttpContext context) =>
{
var path = context.Request.Path.ToUriComponent().Trim('/');
var match = await db.Urls.FirstOrDefaultAsync(x => x.UrlChunk == path);
if (match == null)
return Results.BadRequest("Invalid request");
return Results.Redirect(match?.Url ?? "/");
});
Please post your questions and comments.