7

My goal is to have the url routing as following:

http://www.abc.com/this-is-peter-page

http://www.abc.com/this-is-john-page

What is the simplest way to achieve this without placing controller name an function name in the url above? If page above not found, I should redirect to 404 page.

Addon 1: this-is-peter-page and this-is-john-page is not static content, but is from database.

1
  • Is "this-is-peter-page" a static page or a dynamic one where "this-is-peter-page" would be a field in a database? Commented Jul 2, 2009 at 6:20

3 Answers 3

9

Similar to KingNestor's implementation, you can also do the followings which will ease your work:

1) Write Your Model

public class MyUser{public String UserName{get; set;}}

2) add route to global asax

routes.MapRoute(
   "NameRouting",
   "{name}",
   new { controller = "PersonalPage", action = "Index", username="name" });

3) Roll your own custom model binder derived from IModelBinder

public class CustomBinder : IModelBinder
    {
       public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
       {
          var request = controllerContext.HttpContext.Request;
          var username = getUserNameFromDashedString(request["username"]);
          MyUser user = new MyUser(username);

          return user;
       }
    }

4) in your action:

public ActionResult Index([ModelBinder(typeof(CustomBinder))] MyUser usr)
{
    ViewData["Welcome"] = "Viewing " + usr.Username;
    return View();
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks to Zhaph for re-arrange step 3 and step 4
I found bindingContext doesn't containing HttpContext
4

I personally wouldn't suggest a route like that but if it meets your needs you need to do something like:

Have the following route in your Global.asax file:

    routes.MapRoute(
       "NameRouting",
       "{name}",
       new { controller = "PersonalPage", action = "routeByName" });

Then, in your "PersonalPageController", have the following method:

    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult routeByName(string name)
    {
         switch (name)
         {
             case "this-is-peter-page": return View("PeterView");
             case "this-is-john-page": return View("JohnView");
             case Default: return View("NotFound");
         }
    }

Make sure you have the appropriate views: "PeterView", "JohnView" and "NotFound" in your Views/PersonalPage/.

4 Comments

You could combine that with a route constraint to prevent 'unwanted' requests to go to that controller. (I assume that you still need some other controller)
how to prevent 'unwanted' request?
@Ervin Ter, you can provide route constraints that constrain this route to a particular regular expression.
@Simucal, I see. Never know that we can plant regular expression on route.
2

I don't think this can be done. AFAIK ASP.NET MVC recognizes routing parameters via the character "/".

Your format, on the other hand, goes by "{controller}-is-{id}-{action}" -- so there is no way the controller can be distinguished from the id and the action.

I think using "/" characters doesn't affect or degrade SEO; it only affects human readability and retention of the URL.

Anyway, the following URL is possible: http://www.abc.com/this-is-the-page-of/Peter by adding another route in the Global.asax RegisterRoutes method:

        routes.MapRoute(
            "AnotherRoute",
            "this-is-the-page-of/{id}",
            new { controller = "PersonalPage", action = "Details", id = "" }
        );

...assuming that PersonalPageController implements a Details ActionResult method that points to the desired page.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.