I am trying to do what SO does for its Question controller.
/Posts/{id}/{title} when viewing a post (action name not shown)
/Posts/New when you are posting something new.
/Posts/Delete/10 etc....
I have two routes set up (well, one if you don't count the default). What appears to be happening is all actions in the Post controller are being routed through the first one.
What is that? I obviously have it wrong, but I can't figure this out.
routes.MapRoute("ViewPosts",
"Posts/{postid}/{title}",
new { controller = "Posts", action = "View", postid = "", title = "" });
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
The first route handles all your requests which starts from /Posts.
You need to use constraints to allow {postid} be only number:
routes.MapRoute("ViewPosts",
"Posts/{postid}/{title}",
new { controller = "Posts", action = "View", postid = "", title = "" },
new { postid= #"\d+" });
In this case only if numeric Id is provided this route will handle it, otherwise "Default" route will handle.
All routes are going through the first because you have not specified that the postid field can only be numeric, or defined an earlier route that will catch /Posts/New. It is passing New as the postid with the View action.
You can add this route definition before the ones you have now:
routes.MapRoute("NewPost",
"Posts/New",
new{controller="Posts", action="New"});
Or whatever the appropriate controller/action would be.
Related
I have two controllers with identical names, one of which lives in the "Admin" area and one in the default area (which I believe resolves as an empty string for area).
The following call:
HtmlHelper.Action("Action", "DuplicateController", new { parameterValue = "test" } );
Doesn't appear to be able to resolve the difference between my ProjectA.Controllers.DuplicateController and ProjectB.Controllers.DuplicateController, even if I specify the area as "" by adding it as follows:
HtmlHelper.Action("Action", "DuplicateController", new { parameterValue = "test", area = "" } );
I know I should be able to resolve this by specifying a route when I register them on application startup, but is it possible to specify a fully-qualified namespace directly to the controller I know I need to call right in the action method?
e.g. something like the following would solve my problem:
HtmlHelper.Action("Action", "ProjectB.Controllers.DuplicateController", new { parameterValue = "test" } );
Like you suggested, I believe you'll have to add namespaces to the routes for both of your ambiguous controllers in your RouteConfig.cs file and your AdminAreaRegistration.cs file. For an example, see this StackOverflow post.
So, you can either add the "namespaces" argument to the default route as in the above post or create a route for each "Duplicate" controller.
In your RouteConfig.cs:
routes.MapRoute(
name: "Duplicate",
url: "Duplicate/{action}/{id}",
defaults: new { controller = "Duplicate", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "MyMvcApplication.Controllers" }
);
And in your AdminAreaRegistration.cs:
context.MapRoute(
"Admin_Duplicate",
"Admin/Duplicate/{action}/{id}",
new { controller = "Duplicate", action = "Index", id = UrlParameter.Optional },
new[] { "MyMvcApplication.Areas.Admin.Controllers" }
);
The C# MVC 3 Routing i have a controller name Category.
There are 2 Sub Method of the Controller
1)Index
2)Detail
now my detail routing URl coming like this "Category/name" ok but i also want to Add "category/Name-for-all" hard code "-for-all"
want to add this hard code how ?
routes.MapRoute(
"categorie", // Route name
"Category/{id}/{no}", // URL with parameters
new { controller = "Category", action = "details", id = "id",no=UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"categories", // Route name
"Category/{id}/{action}", // URL with parameters
new { controller = "Category", action = "action", id = "id" } // Parameter defaults
);
html page
<div class="grid_3" >
<a class="companyanchor" href="/category/#Model.name/">#Model.Name</a>
</div>
Its hard to understand your question, as I understand you asking about hard coded part of url? Something like this:
routes.MapRoute(null,
"{category}/Page{page}", // Matches /Football/Page567
new { controller = "Product", action = "List" }, // Defaults
new { page = #"\d+" } // Constraints: page must be numerical
);
I have not worked with MVC recently, but isn't this the answer?
routes.MapRoute("categories", // Route name
"Category/{id}"-for-all/{action}", // URL with parameters
new { controller = "Category", action = "action", id = "id" } // Parameter defaults
);
... not sure where "Name" comes from in your example.
I'm having a problem trying to get routing to work with ASP.NET MVC 3.0. I have the following routes declared:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "RsvpForm", id = UrlParameter.Optional }
);
routes.MapRoute(
"TestRoute",
"{id}",
new { controller = "Product", action = "Index3", id = UrlParameter.Optional }
);
routes.MapRoute(
"TestRoute2",
"{action}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
When I visit:
http://localhost
The site works correctly, and it appears to hit Default route.
When I visit:
http://localhost/1
I get a 404:
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is
temporarily unavailable. Please review the following URL and make
sure that it is spelled correctly.
Requested URL: /1
Here are the actions those routes correspond to:
public ActionResult Index3(int? id)
{
Product myProduct = new Product
{
ProductID = 1,
Name = "Product 1 - Index 3",
Description = "A boat for one person",
Category = "Watersports",
Price = 275M
};
Product myProduct2 = new Product
{
ProductID = 2,
Name = "Product 2 - Index 3",
Description = "A boat for one person",
Category = "Watersports",
Price = 275M
};
ViewBag.ProcessingTime = DateTime.Now.ToShortTimeString();
if (id == 1)
return View("index", myProduct);
else
return View("index", myProduct2);
}
How do I structure my routes so that all three action methods are hit correctly?
ASP.NET MVC Routing evaluates routes from top to bottom. So if two routes match, the first one it hits (the one closer to the 'top' of the RegisterRoutes method) will take precedence over the subsequent one.
With that in mind, you need to do two things to fix your problem:
Your default route should be at the bottom.
Your routes need to have constraints on them if they contain the same number of segments:
What's the difference between:
example.com/1
and
example.com/index
To the parser, they contain the same number of segments, and there's no differentiator, so it's going to hit the first route in the list that matches.
To fix that, you should make sure the routes that use ProductIds take constraints:
routes.MapRoute(
"TestRoute",
"{id}",
new { controller = "Product", action = "Index3", id = UrlParameter.Optional },
new { id = #"\d+" } //one or more digits only, no alphabetical characters
);
There are other issues with your set up, but those are two things that come to mind right off the bat.
Your routes MapRoute Default should be the last.
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "RsvpForm", id = UrlParameter.Optional }
);
Push the most generic route to the last of the MapRoute call chain.
Try this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"TestRoute",
"{id}",
new { controller = "Product", action = "Index3", id = UrlParameter.Optional }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "RsvpForm", id = UrlParameter.Optional } // Parameter defaults
//new { controller = "Product", action = "Index2", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"TestRoute2",
"{action}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Move your Default route to the end, Default route should be the last route to define because it acts as a catch all route
In my case, the answer for the same problem was a matter of needing to "include in project" the relevant controllers and views instead of incorrect routing rules.
When mine were created, they weren't automatically included for some reason. This problem was revealed after I closed and re-opened the solution.
{+1 hate} awarded to Visual Studio for its faulty hyper-automation sending me digging through Web.Config files, trying to tack on extensions, and even trying (and failing) to whip up a decent ErrorController.
My application is multilingual and I wrote the following route in order to handle the languages:
routes.MapRoute(
"Default", // Route name
"{language}/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index",
language = "pt", id = UrlParameter.Optional }, // Parameter defaults
new { language = #"(pt)|(es)|(en)" }
);
This works for domain.com and domain.com/pt/home/index. However, if I type domain.com/home/index it fails (404).
The desired behavior would be it being redirected to domain.com/pt/home/index (pt is the default language).
Whats the best way to achieve this? I've been reading a lot about routes and ActionFilters but nothing seems quite right.
i would suggest using custom route handler like following
public class LanguageRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
IRouteHandler handler = new MvcRouteHandler();
var vals = requestContext.RouteData.Values;
if(vals["language"] == null)
{
vals["language"] = "pt";
}
return handler.GetHttpHandler(requestContext);
}
}
and have another route without language route value and set its route handler (global.asax)
routes.MapRoute(
"Default2", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
).RouteHandler = new LanguageRouteHandler();
This will not redirect Home/index to pt/home/index yet it will provide language = "pt" to your index action method (and all others). if you want to redirect you can implement an actionfilter but redirecting will create problems with post requests. For example when you post a form to /home/index and suppose it is redirected by action filter, the redirected request will lose posted form data
You need two routes, the other one without the language, or add the language parameter at the end
Try this
routes.MapRoute(
"Default", // Route name
"{language}/{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new { language = #"(pt)|(es)|(en)" }
);
and modify your action in this way
public ActionResult Index([DefaultValue("pt")] string language)
{
...
}
Could someone show me how to use the MapRoute method? I have tried creating my own routes, but it's not working. What i want to accomplish is a route that routes "http://servername/home/default.aspx" into controller "Home" and action "Default". Also, would it be possible to say that if the user is browsing the default.aspx "file", it would actually point to the "Index" action?
I have tried reading the MSDN references and googling, but it didn't make me any wiser.
Probably too late to help the developer who raised the question but may help someone else. New to MVC but what I found is the map routes seem to be processed in the order they are added. I had a similar problem, my specific route was not working until I started adding the default route as the last route.
If the default map route is added before your custom one and your custom URL matches the structure defined by the default map route you will never reach your custom route.
The route you want to configure the first part of your question is:
routes.MapRoute(
"",
"home/default.aspx",
new { controller = "Home", action = "Default" }
);
Assuming you wish to 'browse' default.aspx with some sort of parameter you can do something like:
routes.MapRoute(
"",
"home/default.aspx/{param}",
new { controller = "Home", action = "Default", param = UrlParameter.Optional }
);
And you would then need to create your Default action to accept string param.
You also have to make sure the parameter name is the same as the action's parameter name.
Example:
routes.MapRoute(
name: "MyName",
url: "{controller}/{action}/{myParam}",
defaults: new { controller = "MyController", action = "MyAction", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
MyController:
public ActionResult MyAction(string myParam = "")
{
}