xTRUMANx
xTRUMANx

Reputation: 1035

Routing simplification

I'm working on a project using ASP.NET MVC3 RC1 and was wondering if my routes can be simplified.

I've got this controller action:

public ActionResult Things(DateTime? fromDate, DateTime? toDate, int? pageNo)
    {
        DataLayer dataLayer = new DataLayer();

        int page = pageNo.HasValue ? pageNo.Value : 1;

        List<Thing> things = dataLayer.GetThingsByDateRangePaged(User.Identity.Name, fromDate, toDate, pageNo, PageSize);

        return View(things);
    }

I'd like to be able to access this controller action by the following urls:

I've currently have these routes mapped out:

routes.MapRoute("Things",
    "Things",
    new { controller = "Thing", action = "Things" }
    );

routes.MapRoute("ThingsPaged",
    "Things/Page{pageNo}",
    new { controller = "Thing", action = "Things" }
    );

routes.MapRoute("ThingsCertainPeriod",
    "Things/From{fromDate}/To{toDate}",
    new { controller = "Thing", action = "Things" }
    ); 

routes.MapRoute("ThingsCertainPeriodPaged",
     "Things/From{fromDate}/To{toDate}/Page{pageNo}",
     new { controller = "Thing", action = "Things" }
     );

Seems to me that my routes are ripe for refactoring but I'm not entirely sure how to get rid of the redundancy. UrlParameter.Optional doesn't seem to work like how I thought it did when I experimented with it. Can my routes be simplified to one route?

Upvotes: 1

Views: 104

Answers (1)

Steve
Steve

Reputation: 15736

I don't think you can match things/page2 and things/from11-14-2010/... with the same route because it only makes sense to have an optional value at the end of a route. However you can cut it down to just two routes:

routes.MapRoute(
   "Thing1",
   "Thing/Thing/{from}/{to}/{page}",
   new { controller = "Thing", action = "Thing", page = 1 },
   new { from = @"(\d{1,2}-\d{1,2}-\d{4})?", to = @"(\d{1,2}-\d{1,2}-\d{4})?" }
);

routes.MapRoute(
   "Thing2",
   "Thing/Thing/{page}",
   new { controller = "Thing", action = "Thing", page = 1 },
   new { page = @"(\d*)?" }
);

You can eliminate the page, to and from prefixes by using regex constraints to match the parameters.

You can also simplify the controller by setting the default value for page (1) in the route, so that it need not be a nullable. Otherwise you would have to use UrlParameter.Optional for the page value in the first route.

Upvotes: 1

Related Questions