RedirectToAction with no parameter action on url
I am following this post RedirectToAction with parameter to do this
return RedirectToAction("index","service",new {groupid = service.GroupID});
for some reason, the url it returns is not what was expected. For example, instead of http: // localhost / appname / service / index? Groupid = 5, it returns http: // localhost / appname / service? Groupid = 5 . Is there a way to return the expected URL?
Update: RouteConfig.cs
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
thank
source to share
What happens is that your default route is defined as
url: "{controller}/{action}/{id}",
but the method Index()
has no parameter named id
(its groupId
), so the routing engine uses the default for {action}
. You can generate the required route by changing the parameter name toid
public ActionResult Index(int id)
and in another method use
RedirectToAction("Index","Service",new {id = service.GroupID})
or add a new route definition before the default route
routes.MapRoute(
name: "Service",
url: "Service/Index/{groupId}",
defaults: new { controller = "Service", action = "Index", groupId = UrlParameter.Optional }
);
Note that in both cases this will result in ../Service/Index/5
, and not to ../Service/Index?groupId=5
, but in any case it works best (if you really need the second option, change the route above to url: "Service/Index",
(omit the last parameter)
source to share
Ok I figured it out and reproduced it in a test environment. This is due to routing.
In MVC, when you use a common path for all routes like you did:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
It will always treat the index as the default action converted to the controller root. This way localhost / somecontroller will always call the index, and url will load the index in either localhost / somecontroller or localhost / somecontroller / index.
There are two ways to solve this problem, starting with the easiest ones.
Solution 1:
In the service controller, don't call your Index method, call it something else like NotIndex, IDoStuff, whatever. It's just that it will redirect the redirect to Service / IDoStuff (w / e). However, this method means localhost / appname / service will create a 404 (since the default action "Index" does not exist).
Solution 2: lets you perform actions named Index
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Home",
url: "Home/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Service",
url: "Service/Index/{id}",
defaults: new { controller = "Service", action = "Index", id = UrlParameter.Optional }
);
Solution 2 Problem Specifying strict routes like this breaks your default route, and if you bind the default all the way back to the original problem by default, because MVC will traverse a set of routes and apply each route to the url until will find one that matches the first that matches the one it uses, if it doesn't find a suitable route, then bam 404 (Page not found / no resource).
However, like you, I want strong urls, not default, so what I did, I used solution 2.
Then to get my root url back Loading Home -> Index I added a rewrite rule for my web.config
<system.webServer>
<rewrite>
<rules>
<rule name="RootRedirect" stopProcessing="true">
<match url="^$" />
<action type="Redirect" url="/Home/Index/{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
To do this, you need to enable UrlRewrite features in IIS (installed) for it to exist in gac / machine config etc.
Also a redirect rule is a permanent redirect rule, so the browser redirects it without making 2 requests to the server as soon as the client's browser visits the site one time before.
source to share