I have an app that is just one controller and one action, but I want to pass two values into that action. The end result that I'm looking for is a url that looks like this http://www.example.com/parameter1/parameter2
So I was thinking that the routing would look like this
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}/{name}",
defaults: new { controller = "Home", action = "Index"}
);
and the controller would look like this
public class HomeController : Controller
{
public ActionResult Index(string id, string name)
{
return View();
}
}
But I'm clearly wrong as it doesn't work. Does anyone know if it's possible under the index action?
Just to clarify, I want 2 parameters in the default action. I'm aware it's possible by having something like http://www.example.com/books/parameter1/parameter2/ but I specifically want http://www.example.com/parameter1/parameter2/
To totally omit the controller and action placeholders in the route you can just remove them.
(Do not remove it from your default route, better create a new one and place it about the default one)
routes.MapRoute(
name: "Default",
url: "{id}/{name}",
defaults: new { controller = "Home", action = "Index"}
);
This route will only work with Index action from HomeController but not with others.
If id is optional, what your URL would look like when it's not entered, but name is?
/Home/Index//name
That's obviously invalid.
Consider using the values in the query string instead of part of the URL.
I used this and this to solve the problem.
Need two Routes and make sure these routes come above the default MVC route:
routes.MapRoute(
name: "with-name",
url: "Home/{action}/{id}/{name}",
defaults: new { controller = "Home", action = "Index"}
//No Optional
);
routes.MapRoute(
name: "without-name",
url: "Home/{action}/{id}",
defaults: new { controller = "Home", action = "Index"}
);
Related
Currently my URL looks like this:
http://localhost:9737/ProfileEdit?writerId=4
But I want it to be something like this:
http://localhost:9737/ProfileEdit/4
This is my Action signature:
public ActionResult ProfileEdit(long writerId)
I tried adding new route in RouteConfig file like this:
routes.MapRoute(
name: "ProfileEdit",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "ProfileEdit", writerId = UrlParameter.Optional }
);
but no luck.. so how do I change the URL format?
The route defines the parameter as id:
url: "{controller}/{action}/{id}"
But you're using writerId:
http://localhost:9737/ProfileEdit?writerId=4
Change the route to match:
url: "{controller}/{action}/{writerId}"
Note that this will facilitate this change on every URL which uses that route.
You can add a Route attribute:
[Route("ProfileEdit/{writerId}")]
public ActionResult ProfileEdit(long writerId)
You have two ways of doing this:
Change your route values to match the name of the parameter in your action url: "{controller}/{action}/{writerId}".
Do the opposite and change the parameter name in your action to match the route values public ActionResult ProfileEdit(long id)
Edit
If you want the same for multiple parameters you need to specify them in the route as well:
routes.MapRoute(
"ProfileEdit",
"{controller}/{action}/{writerId}/{otherParameter}",
new { controller = "Home", action = "ProfileEdit", writerId = "", otherParameter = "" });
routes.MapRoute(
name: "ProfileEdit",
url: "ProfileEdit/{id}",
defaults: new { controller = "Home", action = "ProfileEdit"}
);
I have an AppController and an AccountController. The AppController only has one view, index, which takes query string parameters from the id part of the url.
The default route is as follows: {controller}/{action}/{id}
This means for the query string parameters to work properly, the view name has to be in the url. url/view/id
I would like to hide that part of the url and render that view by default, so users need only go to url/id.
I have tried {controller}/{id} and {controller}/index/{id} but neither work.
I think this would work. Set the url as : "{controller}/{id}" and give it a default action parameter:
routes.MapRoute(
name: "Default",
url: "{controller}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
I need to have a custom route, like the default one, but this one should accept numeric values as strings. Like 0015. If I leave the parameter type as int, the value passed to the controller method get truncated to 15. And I need 0015.
So what I did, I created the following:
routes.MapRoute(
name: "AccRef",
url: "{controller}/{action}/{acc_ref}",
defaults: new { controller = "Company", action = "Index", acc_ref = "" },
constraints: new { acc_ref = #"^\d{1,4}$" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
And the problem is, as I understand, that when I now pass in an integer as "id"
#Url.Action("Method", "Controller", new { id = item.ref})
from the view, the routing still applies the first route to it and the call fails.
How would you go about solving this problem with routing?
Is it possible to have two same routing configurations where one accepts int and another string?
Your AccRef is too greedy.
If you look at the url generated from the Url helper it is:
Controller/Method/id
This matches your first AccRef route as well as the default route.
You have to be more specific with your routes. Also the order you define your routes are important. So you normally want to define greedier routes last.
Phil Haack has a route debugger on nuget (blog post here) which can help you identify route issues.
If you reverse the order like so:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "AccRef",
url: "{controller}/{action}/{acc_ref}",
defaults: new { controller = "Company", action = "Index", acc_ref = "" },
constraints: new { acc_ref = #"^\d{1,4}$" }
);
Your current scenario will work with above change but the url "/Home/Index/5" or "/Company/Index/0015" still matches both the routes. This is because the routes are generic (as correctly pointed out by Bigfellahull).
In your case since both the parameter is of type int, both the routes are matched.
Option 1:
You can add a extra string say "Acc" in the route url to make it more specific.
routes.MapRoute(
name: "AccRef",
url: "{controller}/{action}/{acc}/{acc_ref}",
defaults: new { controller = "Company", action = "Index", acc_ref = "" },
constraints: new { acc_ref = #"^\d{1,4}$" }
);
In this case the url will change to ".Company/Index/acc/0015".
Option 2:
If you can change the parameter type in action method like so:
public class HomeController : Controller
{
public ActionResult Index(string id)
{
}
}
The url will match only one route.
Option 1 and 2 are for example only to explain how you can make routes more specific.
I have been dealing with some issues about routes. I have defined the routes but I keep getting 404. Here are the routes :
routes.MapRoute(
name: "Default",
url: "{controller}",
defaults: new { controller = "Login", action = "Login" }
);
routes.MapRoute(
name: "Home",
url: "{controller}/{Date}",
defaults: new { controller = "Home", action = "Home", Date = UrlParameter.Optional }
);
routes.MapRoute(
name: "Calendar",
url: "{controller}/{action}",
defaults: new { controller = "Calendar", action = "Index" }
);
routes.MapRoute(
name: "Act",
url: "{controller}",
defaults: new { controller = "Act", action = "New" }
);
localhost:51081/login works!
localhost:51081/Home/25.04.2013 works!
localhost:51081/act doesnt work!
localhost:51081/calendar/index doesnt work!
Here "login" and "home" works but "calendar" and "act" doesnt. When I move "calendar" mapping to the top then "home" mapping doesnt work. how do you map your pages?
Basically I dont want action name to appear on the url ex : http://localhost:51081/Home/Home/25.04.2013. I want to see it like http://localhost:51081/Home/25.04.2013 or http://localhost:51081/calendar
Like #MarcGravell says: you only add special rules for the exceptions
In your case routes Calendar and Home are the same.
You can map your routes more specific by replacing {controller} with the Home, cause that route isn't that dynamic and is really an exception(it ignores the action)
routes.MapRoute(
name: "Home",
url: "Home/{Date}",
defaults: new { controller = "Home", action = "Home", Date = UrlParameter.Optional }
);
Act is the same as calendar so you don't need two routes for those. Just call Act/New instead of only Act.
For the Default use:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Login", action = "Login" }
);
And put it at the bottom of your routes off course.
routes.MapRoute(
name: "Default",
url: "{controller}",
defaults: new { controller = "Login", action = "Login" }
);
This defines a route that matches / and /anything; the / will try to use LoginController.Login, and /anything will try to use anythingController.Login. Note that at no point does this route allow it to pick up any "action" other than Login.
If you trow all of those away, and use something like:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
then that will match any of /, /anything and /anything/anythingelse.
/ will map to HomeController.Index
/anything will map to anythingController.Index
/anything/anythingelse will map to anythingController.anythingelse
Hopefully that explains how the mapping works in terms of defaults.
If you have any specific routes, they should be added before this blanket default.
Remember that asp.net routes are evaluated in the order in which you add them to the MapRoute table.
Your "default" and "act" routes are the same, since they have the same pattern. "Act" will probably never get hit.
Also, your "default" route is pretty generic, and most requests will satisfy it. You should add your routes in order of most specific (e.g. hard-coded routes) to least specific (e.g. all placeholders).
So if I have a request of foo/bar, it will fall to your "default" route since "foo" will be interpreted as the controller -- it's then going to look for a resource of "bar" which probably doesn't exist. So you'll get a 404.
Your "home" and "calendar" routes are also the same pattern, so only one will get hit (which will be the first defined).
Make your routes more specific, and define them from most specific to least.
Good luck!
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 = "")
{
}