1110
1110

Reputation: 6829

Is it possible to change url route parameter with another value

I have asp.mvc project. Currently routing is set to form following url's:

site/school/45
site/school/45/courses
site/school/45/teachers
site/school/45/courses/17
etc.

I want to change this '45' (id of the school) to more 'user friendly' name, for example to take 'Name' of school '45'. Now action methods are like:

public ActionResult Index(int schoolId)
{ ...

Is it possible to change routing to display school name instead schoolID without changing action methods?

Upvotes: 3

Views: 4229

Answers (3)

Sergii Kudriavtsev
Sergii Kudriavtsev

Reputation: 10487

"without changing action methods" seems to be the most important part of your question, right?

Yes, you can. You may override OnActionEcecuting(ActionExecutingContext filterContext) method in your controller class to do name-id mapping for you. You need to do the following:

  1. Implement base controller class, something like this:

    public class BaseController: Controller
    {
            protected override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                base.OnActionExecuting(filterContext);
                var shoolName = filterContext.RouteData.Values["schoolName"].ToString();
                var schoolId = ...; // Get school id from name somehow here
                filterContext.RouteData.Values.Add("schoolId", schoolId);
            }
    }
    

    (I assume here that you will change your corresponding routing parameter name from schoolId to schoolName in Global.asax.cs / RegisterRoutes).

  2. Update all your controllers by making them inherit not from Controller but from BaseController, like this:

    public class SomethingController: BaseController
    {
        ...
    }
    

After that everything should be working. You won't need to change your controller actions - schoolId parameter will be already at place when it will come to calling them.

Upvotes: 4

Stephen
Stephen

Reputation: 1737

You will need to add a new route to the global routing to allow for a string name rather than just an int id. The best option would be to create a new method that takes the school name and then (from the database or a cached object/dictionary) translates the name to the id then forwards to the int index method.

Something like this (not shown caching)

public ActionResult Index(string schoolName)
{
 var schoolId = SomeMethodThatGetsTheIdFromString(schoolName)
 RedirectToAction("Index", new { id = schoolId });
}

Upvotes: 2

Rich O'Kelly
Rich O'Kelly

Reputation: 41757

You could achieve this with a custom model binder to figure out the id of the school based on the name and use this to 'bind' to your schoolId parameter.

However, I would suggest leaving your routing the way it is - if a school's name changes for example it would mean that all bookmarks would no longer work, or your url would appear incorrect.

Upvotes: 0

Related Questions