i have two questions. i'm fairly new to MVC and love the new way the controller and views are set up, but i can't figure out how to do the following:
1) make a url like www.homepage.com/coming-soon
for this type of url what is the right way to do it? do you create a controller named ComingSoonController and somehow magically insert a dash via routing? note i do NOT want underscores as that's not in the best interest of SEO. or is coming-soon some action name on some other controller that is not in the URL and use the [ActionName("name-with-dash")] attribute?
2) facebook, linkedin and twitter have urls like www.facebook.com/[profile name]. how would this be done in MVC? obviously the [profile name] is dynamic. and the code would obviously live in a controller called, say, profiles. so it seems to me that you would have to make MVC smart enough to know when that second part of the URL is a profile name and NOT a controller, and route it to the right action on the profiles controller? is this easier than it sounds?
1) It depends if coming-soon is dynamic part or not. I'll presume it is and would suggest something like this:
Global.asax
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"Page", // Route name
"{pageName}", // URL with parameters
new { controller = "Home", action = "Page"} // Parameter defaults
);
}
public class HomeController : Controller
{
public ActionResult Page(string pageName)
{
return View();
}
}
2) You can resolve this same way as I've shown above, but keep in mind that order of routes is important. And that first one that matches wins. If you want two actions that have different logic but similar url structure www.mysite.com/coming-soon and www.mysite.com/{profile name}, presuming that first url has static part and the later dynamic you could do something like this:
Global.asax
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
"Coming-soon", // Route name
"coming-soon", // URL with parameters
new { controller = "Home", action = "ComingSoon" } // Parameter defaults
);
routes.MapRoute(
"Profiles", // Route name
"{profileName}", // URL with parameters
new { controller = "Home", action = "Profile"} // Parameter defaults
);
}
public class HomeController : Controller
{
public ActionResult ComingSoon()
{
return View();
}
public ActionResult Profile(string profileName)
{
return View();
}
}
You could create a custom route handler be allow hyphens in the urls:
Create a new handler
public class HyphenatedRouteHandler : MvcRouteHandler{
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
requestContext.RouteData.Values["controller"] = requestContext.RouteData.Values["controller"].ToString().Replace("-", "_");
requestContext.RouteData.Values["action"] = requestContext.RouteData.Values["action"].ToString().Replace("-", "_");
return base.GetHttpHandler(requestContext);
}
}
...and the new route:
routes.Add(
new Route("{controller}/{action}/{id}",
new RouteValueDictionary(
new { controller = "Default", action = "Index", id = "" }),
new HyphenatedRouteHandler())
);
MVC Hyphenated urls
I've developed an open source NuGet library for the first problem which implicitly converts EveryMvc/Url to every-mvc/url.
Dashed urls are much more SEO friendly and easier to read. (More on my blog post)
NuGet Package: https://www.nuget.org/packages/LowercaseDashedRoute/
To install it, simply open the NuGet window in the Visual Studio by right clicking the Project and selecting NuGet Package Manager, and on the "Online" tab type "Lowercase Dashed Route", and it should pop up.
Alternatively, you can run this code in the Package Manager Console:
Install-Package LowercaseDashedRoute
After that you should open App_Start/RouteConfig.cs and comment out existing route.MapRoute(...) call and add this instead:
routes.Add(new LowercaseDashedRoute("{controller}/{action}/{id}",
new RouteValueDictionary(
new { controller = "Home", action = "Index", id = UrlParameter.Optional }),
new DashedRouteHandler()
)
);
That's it. All the urls are lowercase, dashed, and converted implicitly without you doing anything more.
Open Source Project Url: https://github.com/AtaS/lowercase-dashed-route
When it comes to the second problem, you can do this either by making your own routes or handling not found with a custom error handling mechanism, but the routing will be faster if you restrict the profile urls to concur to some rules (like don't have any slashes) so that you can distinguish it from other urls much more easily, like from content file urls i.e. .css .js etc.