RedirectToAction() generates wrong URL - asp.net

I'm having a problem with MVC 4, and I guess it's something really trivial, but it's been bugging me for the last day and I can't seem to figure it out.
I have this url:
http://www.example.com/my-dashed-url
I have a Controller named:
public class MyDashedUrlController: Controller
{
}
I have only two Routes like this:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("my-dashed-url",
"my-dashed-url/{action}",
new { controller = "MyDashedUrl", action = "Index" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home",
action = "Index",
id = UrlParameter.Optional }
);
I get to the index just fine. However, when I do this:
public ActionResult Index()
{
if (NoUserIsLoggedOn)
return RedirectToAction("Logon", "MyDashedUrl");
return View();
}
public ActionResult Logon()
{
Contact c = GetContact();
return View(c);
}
It doesn't redirect me to the "Logon" action properly.
It should redirect me to:
http://www.example.com/my-dashed-url/logon
but instead it tries to redirect me to:
http://www.example.com/logon
... which doesn't work (404 Not Found)
I'm missing something. Can anyone spot it? If anyone needs any more information, let me know.
And it's EVERY RedirectToAction that does the same thing in this controller. A Html.BeginForm("Logon", "MyDashedUrl") would also generate:
http://www.example.com/logon
I guess it has to do something with the Routes I defined, but I can't find the faulty one, seeing as they're all the same. If I disable all of my Routes besides the default one from MVC, the problem remains the same

Make sure that you have declared this custom route BEFORE the default one:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"my-dashed-url",
"my-dashed-url/{action}",
new { controller = "MyDashedUrl", action = "Index" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
Remember that routes are evaluated in the order you declared them. So the first route that matches a request will be used. If you declare your custom route after the default one, it is the default route that will match the request.

Related

How does RedirectToRoute work and how to pass data in it?

I'm trying to redirect to a route that is in the RecomController and the action is Index, i have defined the path in my RouteConfig file and have also specified an id parameter that i pass when i call my RedirectToRoute function. For some reason it can't find that path.
I have also created a Route attribute above the RecomController Index action but it still doesn't navigate me to that path. Am i missing something?
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 }
);
routes.MapRoute(
name: "Recomroute",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Recom", action = "Index", id = UrlParameter.Optional }
);
}
RecomController.cs:
[Route("Recom/Index")]
public ActionResult Index(int id)
{
............//Functioning
}
Calling the function (IN ANOTHER CONTROLLER):
ProjectController.cs:
return RedirectToRoute("Recom/Index/{id}", new {id = projectdto.Id });
Sounds like you're using wrong route name or path in RedirectToRoute(), hence it doesn't work:
// this is wrong because first parameter did not match
return RedirectToRoute("Recom/Index/{id}", new {id = projectdto.Id });
For two parameters overload, it requires route name (not route path) and route values, as shown in definition below:
protected internal RedirectToRouteResult RedirectToRoute(string routeName,
RouteValueDictionary routeValues)
Hence, you need to provide complete route name and route values defined in RegisterRoutes (e.g. Recomroute).
return RedirectToRoute("Recomroute", new {
controller = "Recom",
action = "Index",
id = projectdto.Id
});
Side notes:
1) You still need to provide controller, action and id parameters in order to match route definition.
2) The Recomroute seem defined below default route with same route segments definition which overrides all custom routes beneath it, if you want to evaluate Recomroute first move it to the top order and use different path against default route.

ASP.net how to make RedirectToRouteResult() to a url configured in MapRoute()

I set a route map in RouteConfig.cs like:
routes.MapRoute(
name: "Default",
url: "prefix/{controller}/{action}",
defaults: new { controller = "MainView", action = "Index" }
);
And I want to do a redirect in MainView/Index under some situation, so I write code like below, and return it:
RedirectToRouteResult redirect = new RedirectToRouteResult(
new System.Web.Routing.RouteValueDictionary(new { action = "Home", controller = "Account"}));
I wish it would return the url like: localhost/prefix/Account/Home, but the result is localhost/Account/Home. How can I make the redirect result to be localhost/prefix/Account/Home?
Thanks!
All right, I made a stupid fault, there is [Authorize] attribute on this action, so the return url is made by this attribute. I correct this code and get the expected url.

ASP.NET routes not triggering as I expect

trying to get started with ASP.NET MVC.
I encountered a few difficulties while setting up basic routes.
My routes are as follows:
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 }
);
routes.MapRoute(
name: "ImproItem",
url: "{controller}/{action}/{type}",
defaults: new { controller = "ImproItemForm", action = "Index", type = UrlParameter.Optional }
);
}
My view calls :
<li>#Html.ActionLink("linkLabel", "Index", "ImproItemForm", new { type = "blablabla" }, null)</li>
My controller action sig is:
public class ImproItemFormController : Controller
{
...
public ActionResult Index(String t)
{
...}
}
The view generates the following HTML:
<li>linkLabel</li>
This looks OK to me.
However, this link correctly calls the controller's action (using ImproItem route) but it does not pass the blablabla argument. The parameter t = null when I debug the app.
Can you explain me why?
What should I change to correctly receive the blablabla argument?
Now if I start the application and try to browse
Also is it normal that when I browse:
http://localhost:55193/ImproItemForm/Index?id=foobar
It does call the ImproItemFormController.Index(String t) method ?
I did not expect that this URL would match with this route:
routes.MapRoute(
name: "ImproItem",
url: "{controller}/{action}/{type}",
defaults: new { controller = "ImproItemForm", action = "Index", type = UrlParameter.Optional }
);
I thought the argument needs to have the same name than in the route : type and not id.
Thx in advance for your help.
I thought the argument needs to have the same name than in the route :
type and not id.
Actually when you request the URL - http://localhost:55193/ImproItemForm/Index?id=foobar, it actually calls the Default route only, and not the custom route that you have created. Default route has - controller name, action name and id. That means, if there is any URL matching this pattern (i.e., {controllername}/{actionname}/{id}) would match the default route.
Order of routes are very important in route collection because route table is built top-to-bottom, so as soon as the URL finds its first matching route, it stops scanning further.So ideally, default route should be the bottom most route in route collection.
I guess all your problems for this particular scenario should be resolved by performing following two steps-
Move default route to the bottom in route collection in RouteConfig.cs
Rename parameter "t" to "type" in Index action.
Change the name of the parameter in your action to match the name in the ActionLink
public ActionResult Index(String type)

MVC action results in 404 with "No type was found that matches the controller" invoking default action on controller works

I inherited some ASP.Net MVC code and am tasked with adding some new features. I am a complete beginner using ASP.Net MVC and come from a background of mainly using Web Forms.
I added a new controller (ApiController) and I added the following actions to it:
// GET: /Api/Index
public string Index()
{
return "API Methods";
}
// GET: /Api/DetectionActivity
public JsonResult DetectionActivity()
{
var detections = from d in db.Detections
orderby DbFunctions.TruncateTime(d.CreationTime)
group d by DbFunctions.TruncateTime(d.CreationTime) into g
select new { date = g.Key, count = g.Count() };
ViewBag.DetectionCounts = detections.ToList();
return Json(detections, JsonRequestBehavior.AllowGet);
}
My RouteConfig.cs has the following registered routes.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Dashboard", action = "Index", id = UrlParameter.Optional }
);
This looks like the tutorials I've been reading but it's not working and I'm probably missing something.
If I go to localhost:21574/api I see the output from the Index() action, "API Methods".
If I go to localhost:21574/api/DetectionActivity it throws a 404 with the following data in the response:
{
"Message":"No HTTP resource was found that matches the request URI 'http://localhost:21574/Api/DetectionActivity'.",
"MessageDetail":"No type was found that matches the controller named 'DetectionActivity'."
}
I'm thinking there is something I need to do that I'm not.
Any suggestions on what to do next?
Update 1
I tried this with my RouteConfig.cs
routes.MapRoute(name: "ApiController",
url: "{controller}/{action}"
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Dashboard", action = "Index", id = UrlParameter.Optional }
);
These were my results:
If I go to localhost:21574/api I see the output from the Index() action, "API Methods". Same as before.
If I go to localhost:21574/api/DetectionActivity it throws a 404 with the following data in the response:
{
"Message":"No HTTP resource was found that matches the request URI 'http://localhost:21574/Api/DetectionActivity'.",
"MessageDetail":"No type was found that matches the controller named 'DetectionActivity'."
}
Same as before.
If I go to localhost:21574/Api/Api/DetectionActivity it throws a 404 with this data in the response:
{
"Message":"No HTTP resource was found that matches the request URI 'http://localhost:21574/Api/Api/DetectionActivity'.",
"MessageDetail":"No type was found that matches the controller named 'Api'."
}
Now it's saying it can't find a controller named "Api".
from your Route Config
the URL should be: localhost:21574/Api/Dashboard/DetectionActivity
or if you really need localhost:21574/Api/DetectionActivity (not recommended)
change your Register method in WebApiConfig class to
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{action}/{id}",
defaults: new { controller = "Dashboard", action = "Index", id = RouteParameter.Optional }
);

ASP.NET MVC3 Route - example.com/blog/projects to example.com/projects

I have an ActionResult in my Blog controller that is returning all the projects called Projects, but my URL looks like example.com/blog/projects, I want to set up route to make it look like example.com/projects.
Is it possible? And if it is then how can I achieve that?
You have to register route following way Global.asax and put this as a first route
routes.MapRoute("Projects", "Projects" , new { controller="blog" , action="Projects" });
You can add a route to your Global.asax.cs file, such as:
routes.MapRoute(
"Projects", // Route name
"Projects/{id}", // URL with parameters
new { controller = "Blog", action = "Projects", id = UrlParameter.Optional } // Parameter defaults
);
So it looks something like this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Projects", // Route name
"Projects/{id}", // URL with parameters
new { controller = "Blog", action = "Projects", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
Make sure you put your new route above the default one otherwise yours will never be hit.

Resources