Exitos
Exitos

Reputation: 29720

Why doesn't my routing work?

Im trying to set up an alternative route on my application...

 routes.MapRoute(
                "x", // Route name
                "{controller}/{action}/{datetime}", // URL with parameters
                new { controller = "Home", action = "Index", datetime = UrlParameter.Optional } // Parameter defaults
            );

I have the action...

public ActionResult GetBlogsByMonth(string datetime)
        {
            if (datetime!= null)
            {
                IList<BlogModel> blogs = (IList<BlogModel>)manager.GetBlogsInMonth(DateTime.Parse(datetime)).ToList();
                return View(blogs);
            }
            else
            {
                return View();
            }
        }

But when I put the debugger on the action the datetime is always null... :-(

Upvotes: 0

Views: 617

Answers (2)

tugberk
tugberk

Reputation: 58434

Probably, your request has been caught by another route. Make sure to put your route at the top when you are registering them.

For example, if you are using this route with the default one, the default one will catch the request, not your custom route if you reference them in the following order:

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);


routes.MapRoute(
    "x", // Route name
    "{controller}/{action}/{datetime}", // URL with parameters
    new { controller = "Home", action = "Index", datetime = UrlParameter.Optional } // Parameter defaults
);

As for the solution, as @Darin suggested, you need to define a constraint because if you put your custom one in front, this time the default one will never be hit.

routes.MapRoute(
    "x", // Route name
    "{controller}/{action}/{datetime}", // URL with parameters
    new { controller = "Home", action = "Index", datetime = UrlParameter.Optional }, // Parameter defaults
    new { datetime = @"^(19|20)\d\d([- /.])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$" }
);

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

The below URLs will be caught by your custom route:

/Poo/Bar/2011-11-31

/Poo/Bar/2011-01-04

/Poo/Bar/2011-01-04

You can change the RegEx for your needs.

Upvotes: 1

saintedlama
saintedlama

Reputation: 6898

When constructing a link to your action you can use a RouteLink instead of an ActionLink. With the RouteLink you can pass a named route name to force the right route is chosen to construct the link. For your example the link should look somehow like this:

@Html.RouteLink("Blog Posts...", "x", new { controller="Blog", action="GetBlogsByMonth" datetime = THEDATETIME })

Hint: You can use the DateTime type in your action as parameter instead of a String type so you can avoid the unnecessary call to DateTime.Parse

Upvotes: 0

Related Questions