Simple ASP.NET MVC Routing

I read several threads in StackOverflow about this, but can't get it to work. I have this at the end of my RegisterRoutes in Global.asax.

routes.MapRoute( "Profile", "{*url}", new { controller = "Profile", action = "Index" } ); 

Basically, I'm trying to get mydomain.com/Username to point to my member profile page. How do I configure my controller and RegisterRoutes for this to work?

Mydomain.com/somethingthatisnotacontrollername is currently receiving a 404 error.

+6
source share
3 answers

A solution that works for your case but is not recommended

You have a predefined set of controllers (usually less than 10) in your application, so you can set a restriction on the controller name and then redirect everything else to the user profile:

 routes.MapRoute( "Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new { controller = "Home|Admin|Reports|..." } ); routes.MapRoute( "Profile", "{username}/{action}", new { controller = "Profile", action = "Details" } ); 

But this will not work if some username matches the name of your controller. This is a small opportunity, based on experience, ends with empirical data, but this is not a 0% chance. When the username matches some controller, it automatically means that it will be processed by the first route, because the restrictions will not fail him.

Recommended Solution

A better way would be to have URL requests like:

 www.mydomain.com/profile/username 

Why do I recommend this? This will make Becasue much easier and cleaner and allow you to have several different profile pages:

  • more www.mydomain.com/profile/username
  • settings www.mydomain.com/profile/username/settings
  • posts www.mydomain.com/profile/username/messages
  • and etc.

The route definition in this case will be as follows:

 routes.MapRoute( "Profile", "Profile/{username}/{action}", new { controller = "Profile", action = "Details" } ); routes.MapRoute( "Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); 
+6
source

has something that matches mydomain.com/Username does not actually work because the routing mechanism is not able to distinguish

mydomain.com/someusername

and

mydomain.com/controllername

What could be possible if your username scheme has a unique set of properties, i.e. is a sequence of 9 digits, you can define a route to check what looks like a username.

 routes.MapRoute("", "UserRoute", "{username}", new { controller = "Profile", action = "Index"}, new { {"username", @"\d{9}"}} ); 

The key point is that you need to provide some way for the routing mechanism to distinguish between the username and the standard action of the controller.

You can learn more about restrictions here.

+2
source

I had such a requirement for my project. What I did was create a route restriction, as shown below:

 public class SeoRouteConstraint : IRouteConstraint { public static HybridDictionary CacheRegex = new HybridDictionary(); private readonly string _matchPattern = String.Empty; private readonly string _mustNotMatchPattern; public SeoRouteConstraint(string matchPattern, string mustNotMatchPattern) { if (!string.IsNullOrEmpty(matchPattern)) { _matchPattern = matchPattern.ToLower(); if (!CacheRegex.Contains(_matchPattern)) { CacheRegex.Add(_matchPattern, new Regex(_matchPattern)); } } if (!string.IsNullOrEmpty(mustNotMatchPattern)) { _mustNotMatchPattern = mustNotMatchPattern.ToLower(); if (!CacheRegex.Contains(_mustNotMatchPattern)) { CacheRegex.Add(_mustNotMatchPattern, new Regex(_mustNotMatchPattern)); } } } public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { var matchReg = string.IsNullOrEmpty(_matchPattern) ? null : (Regex)CacheRegex[_matchPattern]; var notMatchReg = string.IsNullOrEmpty(_mustNotMatchPattern) ? null : (Regex)CacheRegex[_mustNotMatchPattern]; var paramValue = values[parameterName].ToString().ToLower(); return IsMatch(matchReg, paramValue) && !IsMatch(notMatchReg, paramValue); } private static bool IsMatch(Regex reg, string str) { return reg == null || reg.IsMatch(str); } } 

Then in the registration method method:

 routes.MapRoute("", "UserRoute", "{username}", new { controller = "Profile", action = "Index"}, new { username = new SeoRouteConstraint(@"\d{9}", GetAllControllersName())} ); 

The GetAllControllersName method will return the entire controller name in your project, separated by |

 private static string _controllerNames; private static string GetAllControllersName() { if (string.IsNullOrEmpty(_controllerNames)) { var controllerNames = Assembly.GetAssembly(typeof(BaseController)).GetTypes().Where(x => typeof(Controller).IsAssignableFrom(x)).Select(x => x.Name.Replace("Controller", "")); _controllerNames = string.Join("|", controllerNames); } return _controllerNames; } 
+1
source

Source: https://habr.com/ru/post/893652/


All Articles