Database-Driven URL Routing in ASP.NET MVC for SEO-Friendly Dynamic URLs Jeshal kalena June 19, 2019 12 min read In ASP.NET MVC, URL routing is responsible for mapping an incoming browser request to the right controller and action method.By default, MVC URLs usually follow a pattern like this:/Controller/Action/IdFor example:/Company/Index/5This works technically, but it is not always the best option for SEO, user experience, or content-driven websites.A better URL would be:/satva-solutionsor:/company/satva-solutionsThis type of URL is easier to read, easier to share, and more meaningful for search engines. To create this kind of URL in ASP.NET MVC, we can use database-driven URL routing.Database-driven URL routing allows us to store SEO-friendly URL slugs in the database and resolve them dynamically at runtime.When a user visits a URL like /satva-solutions, the application checks the database, finds the matching record, and sends the request to the correct controller action.In this blog, we will learn how to implement database-driven URL routing in an ASP.NET MVC website using custom routes, URL slugs, and a database lookup.What Is Database-Driven URL Routing in ASP.NET MVC?Database-driven URL routing is a technique where URL paths are stored and managed in a database instead of being hardcoded inside route configuration.For example, instead of accessing a company page using this URL:/Company/Index/10we can create a clean, SEO-friendly URL like:/satva-solutionsHere, satva-solutions is a slug stored in the database. When the request comes in, ASP.NET MVC checks the slug, finds the matching company record, and maps the request to:CompanyController -> Index ActionThis approach is useful for: Company profile pages Product pages Blog pages CMS pages Service pages Landing pages Category pages Location-based pagesWhy Use SEO-Friendly Dynamic URLs?SEO-friendly URLs are important because they make your website easier to understand for both users and search engines.Compare these two URLs:/Company/Index/7and:/accounting-software-companyThe second URL gives more context. A user can understand what the page is about before clicking.Search engines can also use the URL structure as one of the signals to understand the page topic.Database-driven SEO-friendly URLs help with: Better readability Better click-through rate from search results Cleaner website structure Easier content management More flexible URL control Better support for CMS-style pages Better handling of dynamic landing pagesFor business websites, SaaS websites, directories, marketplaces, and CMS-driven platforms, database-driven routing gives more control over how pages appear in search results.Default ASP.NET MVC Routing vs Database-Driven RoutingIn a standard ASP.NET MVC application, you will usually find a route like this in RouteConfig.cs:routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } );This route works well for normal MVC pages, but it depends on controller and action names.For example:/Company/Index/5In database-driven routing, we want to resolve the URL based on a database value:/satva-solutionsThen internally, the request should be mapped to:/Company/Index/5The user sees the clean URL, while MVC still executes the correct controller action.Example ScenarioLet’s say we have a company directory website.Each company has a page. Instead of showing company pages like this:/Company/Index/1/Company/Index/2/Company/Index/3we want URLs like this:/satva-solutions/microsoft/google/accounting-software-providerEach slug will be stored in the database. When someone visits /satva-solutions, the application will check the database and find the matching company record.Step 1: Create a Database Table for SEO-Friendly URLsFirst, create a table to store company details and SEO-friendly slugs.Here is an improved version of the table structure:CREATE TABLE [dbo].[Companies] ( [Id] INT IDENTITY(1,1) NOT NULL, [CompanyName] NVARCHAR(250) NOT NULL, [SeoFriendlyName] NVARCHAR(250) NOT NULL, [MetaTitle] NVARCHAR(250) NULL, [MetaDescription] NVARCHAR(500) NULL, [Description] NVARCHAR(MAX) NULL, [Employees] INT NULL, [StartDate] DATETIME NULL, [IsActive] BIT NOT NULL DEFAULT 1, CONSTRAINT [PK_Companies] PRIMARY KEY CLUSTERED ( [Id] ASC ) );It is also a good idea to add a unique index on the slug column:CREATE UNIQUE INDEX IX_Companies_SeoFriendlyName ON [dbo].[Companies] ([SeoFriendlyName]);This ensures that two companies do not use the same URL slug.For example, you should not have two records with the same value:satva-solutionsDuplicate slugs can create routing conflicts and SEO issues.Step 2: Add Sample DataNow add a few sample company records:INSERT INTO [dbo].[Companies] ( CompanyName, SeoFriendlyName, MetaTitle, MetaDescription, Description, Employees, StartDate, IsActive ) VALUES ( 'Satva Solutions', 'satva-solutions', 'Satva Solutions - Software Development Company', 'Learn more about Satva Solutions and its software development services.', 'Satva Solutions is a software development company specializing in custom web and enterprise solutions.', 100, '2013-01-01', 1 );Now, when the user visits:/satva-solutionswe want ASP.NET MVC to load this company record.Step 3: Create the Repository InterfaceCreate an interface named ICompanyRepository.cs.public interface ICompanyRepository { Company GetCompanyById(int id); Company GetCompanyBySeoUrl(string seoFriendlyName); }This interface contains two methods:GetCompanyById fetches the company using the primary key.GetCompanyBySeoUrl fetches the company using the SEO-friendly slug.Step 4: Implement the RepositoryNow create a repository class.public class CompanyRepository : ICompanyRepository { private readonly DataDataContext _context; public CompanyRepository() { _context = new DataDataContext(); } public Company GetCompanyById(int id) { return _context.Companies .FirstOrDefault(x => x.Id == id && x.IsActive); } public Company GetCompanyBySeoUrl(string seoFriendlyName) { if (string.IsNullOrWhiteSpace(seoFriendlyName)) { return null; } seoFriendlyName = seoFriendlyName.Trim().ToLower(); return _context.Companies .FirstOrDefault(x => x.SeoFriendlyName.ToLower() == seoFriendlyName && x.IsActive); } }Important NoteIn production, avoid calling ToLower() directly on database columns if your table becomes large.Instead, store slugs in lowercase format and keep the database collation case-insensitive if suitable for your project.For example, always save slugs like this:satva-solutionsaccounting-software-companyasp-net-mvc-developmentnot like this:Satva SolutionsAccounting Software CompanyASP.NET MVC DevelopmentStep 5: Create the Company ControllerNow create a controller named CompanyController.public class CompanyController : Controller { private readonly ICompanyRepository _companyRepository; public CompanyController() { _companyRepository = new CompanyRepository(); } public ActionResult Index(int id) { var company = _companyRepository.GetCompanyById(id); if (company == null) { return HttpNotFound(); } return View(company); } }This controller action receives the company ID after the URL slug is resolved.For example:/satva-solutionswill internally call:CompanyController -> Index(1)Step 6: Create the Company ViewCreate a view at:Views/Company/Index.cshtmlExample:@model Company @{ ViewBag.Title = Model.MetaTitle ?? Model.CompanyName; ViewBag.MetaDescription = Model.MetaDescription; } <h1>@Model.CompanyName</h1> <p>@Model.Description</p> @if (Model.Employees.HasValue) { <p>Employees: @Model.Employees</p> } @if (Model.StartDate.HasValue) { <p>Started On: @Model.StartDate.Value.ToString("dd MMM yyyy")</p> }This view displays the company details based on the database record.You can also use the MetaTitle and MetaDescription fields to dynamically manage SEO metadata.Step 7: Configure Custom Route in RouteConfig.csOpen the RouteConfig.cs file.We need to register a custom route before the default MVC route.public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "SeoFriendlyCompanyRoute", url: "{seoFriendlyName}", defaults: new { controller = "Company", action = "Index" }, constraints: new { seoFriendlyName = new SeoFriendlyRouteConstraint() } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } }Why Route Order MattersRoute order is very important in ASP.NET MVC.The MVC routing engine checks routes from top to bottom. If the default route is placed before the custom SEO route, your dynamic slug route may never execute correctly.So, always place specific custom routes before the default route.Step 8: Create a Custom Route ConstraintNow create a custom route constraint to check whether the incoming URL exists in the database.public class SeoFriendlyRouteConstraint : IRouteConstraint { public bool Match( HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { if (!values.ContainsKey(parameterName)) { return false; } var seoFriendlyName = values[parameterName] as string; if (string.IsNullOrWhiteSpace(seoFriendlyName)) { return false; } var repository = new CompanyRepository(); var company = repository.GetCompanyBySeoUrl(seoFriendlyName); return company != null; } }This constraint checks whether the URL slug exists in the database.If the slug exists, the route is matched.If the slug does not exist, ASP.NET MVC continues checking the next route.Step 9: Create a Custom Route Class to Pass the Company IDThe route constraint only checks whether the slug exists. But we also need to pass the company ID to the controller action.For this, we can create a custom route class.public class SeoFriendlyRoute : Route { public SeoFriendlyRoute(string url, IRouteHandler routeHandler) : base(url, routeHandler) { } public override RouteData GetRouteData(HttpContextBase httpContext) { RouteData routeData = base.GetRouteData(httpContext); if (routeData == null) { return null; } var seoFriendlyName = routeData.Values["seoFriendlyName"] as string; if (string.IsNullOrWhiteSpace(seoFriendlyName)) { return null; } var repository = new CompanyRepository(); var company = repository.GetCompanyBySeoUrl(seoFriendlyName); if (company == null) { return null; } routeData.Values["controller"] = "Company"; routeData.Values["action"] = "Index"; routeData.Values["id"] = company.Id; return routeData; } }This custom route reads the slug from the URL, checks the database, and passes the company ID to the controller.Step 10: Add an Extension Method for Custom Route MappingTo make route registration cleaner, create a route extension method.public static class SeoFriendlyRouteExtensions { public static Route MapSeoFriendlyRoute( this RouteCollection routes, string name, string url, object defaults, string[] namespaces) { if (routes == null) { throw new ArgumentNullException("routes"); } if (url == null) { throw new ArgumentNullException("url"); } var route = new SeoFriendlyRoute(url, new MvcRouteHandler()) { Defaults = new RouteValueDictionary(defaults), DataTokens = new RouteValueDictionary() }; if (namespaces != null && namespaces.Length > 0) { route.DataTokens["Namespaces"] = namespaces; } routes.Add(name, route); return route; } }Now update RouteConfig.cs like this:public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapSeoFriendlyRoute( name: "SeoFriendlyCompanyRoute", url: "{seoFriendlyName}", defaults: new { controller = "Company", action = "Index" }, namespaces: new[] { "YourProject.Controllers" } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } }Replace YourProject.Controllers with your actual project namespace.Step 11: Register Routes in Global.asaxOpen Global.asax.cs and make sure routes are registered inside Application_Start.protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); }Now your custom database-driven routing setup is ready.Step 12: Test the SEO-Friendly URLRun the application and visit:/satva-solutionsThe application should: Read satva-solutions from the URL. Check the Companies table. Find the matching company record. Pass the company ID to CompanyController. Load the company details page.Internally, it works like:/satva-solutionsmaps to:/Company/Index/1But the user only sees the SEO-friendly URL.Handling Invalid URLsWhat happens if someone visits a URL that does not exist?Example:/random-invalid-companyIn this case, the application should return a proper 404 page.Do not redirect every invalid URL to the home page. That can create SEO confusion and poor user experience.A better approach is:if (company == null) { return HttpNotFound(); }You can also create a custom 404 page for better branding and navigation.Performance Best Practices for Database-Driven RoutingDatabase-driven routing is powerful, but if not handled properly, it can create performance issues.Every request may trigger a database lookup. For high-traffic websites, this can become expensive.Here are a few best practices.1. Cache URL SlugsInstead of checking the database for every request, cache active slugs.Example:public Company GetCompanyBySeoUrl(string seoFriendlyName) { string cacheKey = "company_slug_" + seoFriendlyName; var cachedCompany = HttpRuntime.Cache[cacheKey] as Company; if (cachedCompany != null) { return cachedCompany; } var company = _context.Companies .FirstOrDefault(x => x.SeoFriendlyName == seoFriendlyName && x.IsActive); if (company != null) { HttpRuntime.Cache.Insert( cacheKey, company, null, DateTime.Now.AddMinutes(30), Cache.NoSlidingExpiration ); } return company; }This reduces repeated database calls.2. Add a Unique Index on SlugAlways index the slug column:CREATE UNIQUE INDEX IX_Companies_SeoFriendlyName ON [dbo].[Companies] ([SeoFriendlyName]);This improves lookup speed and prevents duplicate URLs.3. Avoid Catching Static FilesYour dynamic route should not interfere with static files like:/style.css/logo.png/script.jsMake sure static files are handled correctly by IIS and ignored from unnecessary route checks.4. Keep Slugs SimpleUse clean slugs like:satva-solutionsasp-net-mvc-developmentaccounting-software-companyAvoid slugs like:Satva Solutions!!!company?id=10asp.net mvc development companySEO Best Practices for ASP.NET MVC Dynamic URLsDatabase-driven routing helps create clean URLs, but URL structure is only one part of SEO.To get better SEO results, follow these practices.1. Use Lowercase URLsGood:/satva-solutionsAvoid:/Satva-SolutionsLowercase URLs are easier to manage and reduce duplicate URL issues.2. Use Hyphens Between WordsGood:/asp-net-mvc-developmentAvoid:/asp_net_mvc_developmentHyphens are more readable and commonly used in SEO-friendly URLs.3. Keep URLs Short and MeaningfulGood:/custom-software-developmentAvoid:/company/details/custom-software-development-company-profile-page-2025Shorter URLs are easier to read and share.4. Add Canonical TagsIf the same content can be accessed from multiple URLs, add a canonical tag.Example:<link rel="canonical" href="https://www.example.com/satva-solutions" />This helps search engines understand the preferred version of the page.5. Use 301 Redirects When Slugs ChangeIf you update a slug from:/satva-solutions-oldto:/satva-solutionsadd a 301 redirect from the old URL to the new one.This helps preserve SEO value and prevents broken links.6. Generate a Dynamic XML SitemapIf your URLs are stored in the database, your sitemap should also be generated from the database.Example sitemap entries:<url> <loc>https://www.example.com/satva-solutions</loc> <lastmod>2026-05-08</lastmod> </url>A dynamic sitemap helps search engines discover your database-driven pages.Common Mistakes to Avoid1. Placing the Default Route Before the Custom RouteWrong:routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); routes.MapSeoFriendlyRoute(...);The custom route may never execute properly.Place the custom route first.2. Not Handling Duplicate SlugsIf two records have the same slug, the application may load the wrong page.Always keep slugs unique.3. Missing 404 HandlingDo not send all invalid URLs to the home page.Use:return HttpNotFound();or a proper custom 404 page.4. Querying the Database on Every RequestFor high-traffic websites, this can slow down the application.Use caching for slug lookups.5. Using Long or Unclear SlugsAvoid URLs that are too long, unclear, or stuffed with keywords.Good URLs should be readable and natural.Database-Driven Routing vs URL RewritingDatabase-driven routing and URL rewriting are sometimes confused, but they are not the same.PointDatabase-Driven RoutingURL RewritingPurposeMaps URL to MVC controller/actionRewrites one URL path to anotherLogic LocationASP.NET MVC route systemIIS, middleware, or rewrite rulesDatabase LookupYes, usuallyNot alwaysBest ForDynamic pages, CMS pages, SEO slugsRedirects, legacy URL changesExample/satva-solutions maps to Company/Index/1/old-page rewrites to /new-pageFor MVC applications where content is managed from the database, database-driven routing is usually the better choice.Can We Use This in ASP.NET Core MVC?The concept is the same, but the implementation is different.ASP.NET Core MVC uses endpoint routing and middleware-based configuration instead of the classic RouteConfig.cs approach.If you are working with ASP.NET Core MVC, you would typically configure routing inside Program.cs or use custom route value transformers.This blog focuses on classic ASP.NET MVC websites.ConclusionDatabase-driven URL routing in ASP.NET MVC is a practical way to create clean, dynamic, and SEO-friendly URLs.Instead of exposing technical URLs like:/Company/Index/5you can create readable URLs like:/satva-solutionsThis improves user experience, supports better SEO structure, and gives your application more flexibility when managing dynamic content.The key steps are: Store SEO-friendly slugs in the database. Create a repository method to fetch records by slug. Configure a custom MVC route. Resolve incoming URLs dynamically. Handle invalid URLs with 404 pages. Use caching and indexes for better performance. Follow SEO best practices like canonical URLs, lowercase slugs, and 301 redirects.If you are building an ASP.NET MVC website with dynamic pages, product pages, company profiles, or CMS-driven content, database-driven routing can help you create a cleaner and more search-friendly URL structure.Need help improving or modernizing your ASP.NET MVC application?Satva Solutions helps businesses build, maintain, and upgrade ASP.NET MVC, ASP.NET Core, and custom .NET applications.Whether you need SEO-friendly routing, performance improvement, custom development, or legacy application modernization, our team can help you build a reliable solution.Talk to our ASP.NET MVC development team today. Contact usFAQsWhat is database-driven URL routing in ASP.NET MVC?Database-driven URL routing in ASP.NET MVC is a technique where URL slugs are stored in the database and resolved dynamically when a request comes in. The application checks the slug, finds the matching record, and maps it to the correct controller action.Why should I use SEO-friendly URLs in ASP.NET MVC?SEO-friendly URLs are easier for users and search engines to understand. A URL like /satva-solutions is more readable than /Company/Index/5 and gives better context about the page content.How do I map a database slug to a controller action in MVC?You can create a custom route or route constraint that reads the incoming slug, checks it against the database, and then assigns the correct controller, action, and ID values to the route data.Should I cache database-driven routes?Yes. If your website gets regular traffic, caching slug lookups can improve performance and reduce database load.What should happen if the slug does not exist?If the slug does not exist, the application should return a proper 404 page. Avoid redirecting all invalid URLs to the home page.Can I use database-driven routing for blog pages?Yes. This approach works well for blog pages, CMS pages, product pages, service pages, category pages, and landing pages.Is database-driven routing good for SEO?Yes, when implemented correctly. It helps you create readable, keyword-friendly URLs and gives better control over dynamic page URLs.