I have an action like this:
[HttpGet]
[Route("~/books/{id:int:min(1)}/{slug?}")]
public ActionResult Book(int? id, string slug)
{
if (slug == null)
{
slug = "awesome-book";
return RedirectToAction("Book", new { id, slug });
}
etc.
}
The problem is that the new route is generated like 'books/1?slug=awesome-book' and that's not what I wanted but 'books/1/awesome-book'. How can I properly set the slug?
This is a problem with generating route URLs. Since the slug
route param is optional, the routing framework stops at /books/1
and then tacks on any params not covered by the URL as a query string, which in this case includes slug
. This is due to the short circuiting system the routing framework employs and there's really nothing you can do about it.
There is a workaround, though. If instead of using an optional param, you use another route, you can name that route and then reference it explicitly. For example:
[Route("~/books/{id:int:min(1)}", Order = 1)]
[Route("~/books/{id:int:min(1)}/{slug}", Order = 2, Name = "BookWithSlug")]
Then, you can generate the URL with:
return RedirectToRoute("BookWithSlug", new { id, slug });
And, you'll end up with the URL you want.