Switching to {controller} / {id} / {action} aborts RedirectToAction

I am trying to use the correct REST URLs with MVC . To do this, I turned off the default routing from:

 {controller}/{action}/{id} 

to

 {controller}/{id}/{action} 

therefore instead of:

 /Customer/Approve/23 

now exists

 /Customer/23/Approve 

ActionLink seems to work fine, but the following code in the CustomerController:

 [CustomAuthorize] [HttpGet] public ActionResult Approve(int id) { _customerService.Approve(id); return RedirectToAction("Search"); //Goes to bad url } 

ends with URL /Customer/23/Search . While he has to go /Customer/Search . Somehow he recalls 23 (id) .

Here is my routing code in global.cs

  routes.MapRoute( "AdminRoute", // Route name "{controller}/{id}/{action}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new { id = new IsIntegerConstraint() } ); routes.MapRoute( "Default", "{controller}/{action}", new { controller = "Home", action = "Index" }); 

If I switch two functions, RedirectToAction will start working, but using:

 Html.ActionLink("Approve", "Approve", new { Id = 23}) 

Now generates /Customer/Approve?id=23 instead of /Customer/23/Approve .

I could specify direct URLs like ~/Customer/23/Approve instead of using ActionLink and RedirectToAction , but would prefer to stick with the functions provided by MVC .

+8
url-routing asp.net-mvc-3 asp.net-mvc-routing
source share
6 answers

Try passing a new (empty) RouteValueDictionary in the controller

 return RedirectToAction("Search", new System.Web.Routing.RouteValueDictionary{}); 

And here:

 Html.ActionLink("Approve", "Approve", new { Id = 23}) 

I don’t even know how it can pick up a Customer controller, since you did not specify it anywhere. Try turning on the controller and action in the ActionLink assistant.

+1
source share

When you use RedirectToAction (), inside MVC will use the existing route data (including the Id value) to create the URL. Even if you pass a null RouteValueDictionary document, existing route data will be merged with the new empty route data.

The only way I can see is using RedirectToRoute () as shown below:

 return RedirectToRoute("Default", new { controller = "Customer", action = "Search"}); 

advsellorben

+1
source share

Try passing the current route data to the meton in your controller action:

 return RedirectToAction("Search", this.RouteData.Values); 
0
source share

Delete this part:

 id = UrlParameter.Optional 

can solve the problem; when you define "id" as an optional parameter and you have a card "Default", "Default" and "AdminRoute" are the same together! Sincerely.

0
source share

I had a similar problem. The route values ​​that were passed to my controller action were reused when trying to redirect the user using RedirectToAction , even if I did not specify them in the new RouteValueDictionary . The solution I came across (after reading the advsellorben post) in order to clear RouteData strong> for the current request. That way, I could stop MVC from merging route values ​​that I didn't specify.

So, in your situation, perhaps you could do something like this:

 [CustomAuthorize] [HttpGet] public ActionResult Approve(int id) { _customerService.Approve(id); this.RouteData.Values.Clear(); //clear out current route values return RedirectToAction("Search"); //Goes to bad url } 
0
source share

I had a similar problem, and I was able to solve it by adding an identifier to the default route.

 routes.MapRoute( "Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }); 

If there really is no identifier in your default path, you can also try:

 routes.MapRoute( "Default", "{controller}/{action}", new { controller = "Home", action = "Index", id = string.Empty }); 
0
source share

All Articles