R – ASP.NET routing with optional URL segments

asp.netasp.net-mvcasp.net-mvc-routingrouting

I'm working on an ASP.NET MVC task list and I'd like to get fancy with the URL routing when filtering the list. I have an action method defined like this:

public ActionResult List(int categoryID, bool showCompleted, TaskFilter filter);

enum TaskFilter { MyTasks, MyDepartmentTasks, AllTasks }

I want my URLs to look like this:

/Tasks/Category4/MyTasks/ShowCompleted/
/Tasks/Category4/MyDepartment
/Tasks/Category4/

The Category# segment will always be present. I'd like the MyTasks|MyDepartment|AllTasks segment to be optional, defaulting to AllTasks if absent. I'd also like ShowCompleted to be optional, defaulting to false.

Is this sort of routing possible, or am I going to have to fall back and just use querystring parameters?

Followup/extra credit question: What if I also wanted a fourth parameter on the action method to filter by task due date that looked like Today|Day2Through10 (default Today if absent)?

Best Answer

The following covers your first question with a slight change:

routes.MapRoute(
    "t1",
    "Tasks/Category{categoryID}",
    new
    {
        controller = "Task",
        action = "List",
        showCompleted = false,
        strFilter = TaskFilter.AllTasks.ToString()
    }
    );

routes.MapRoute(
    "t2",
    "Tasks/Category{categoryID}/{strFilter}/",
    new
    {
        controller = "Task",
        action = "List",
        showCompleted = false
    }
);

routes.MapRoute(
    "t3",
    "Tasks/Category{categoryID}/{strFilter}/ShowCompleted",
    new { controller = "Task", action = "List", showCompleted = true }
    );

You will need to change the List method to start like the following:

public ActionResult List(int categoryID, bool showCompleted, string strFilter)
{
    TaskFilter filter = (TaskFilter)Enum.Parse(typeof(TaskFilter), strFilter);

For your second query, you just need to use {Day2} and such to be passed to the ActionResult. You should be able to figure it out from what I've given you.