I have problem with routing in my mvc app. I have my core app with ProductsController and extension that is loaded in "PreApplicationStartMethod". In this extenstion i register route like this:
routes.MapRoute(
name: "ProductDetails",
url: "Products/Details/{id}",
defaults: new { controller = "StandardProductsDetails", action = "Details" },
namespaces: new []{ "Shop.Controllers" }
);
And in my core app im not registering specific route for ProductsController but I have a general route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "Shop.Controllers" }
);
Now when I enter /Products/Details/1 in web browser im redirectd to ProductsController.
Oderd of adding routes is specific first, general last. I've checked routes table and my route is existing in it.
I think you are using two projects here, if you are using then make the project as startup project(by right click) which you want to hit first.
Related
I newbie on MVC5 so I got many troubles which one is
Instead of typing Home/Index/ID, I type /ID it still understand. How can I do that?
In your routes config file use the following route:
routes.MapRoute(
name: "Default",
url: "{id}",
defaults: new { controller = "Home", action = "Index" }
);
Now lets say your website name is localhost:5050 when you will hit localhost:5050/abc it will open Index action of Home controller with id = abc
I have added WCF service to MVC 5 application, and created a route for it:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add(new ServiceRoute("Service1.svc", new ServiceHostFactory(), typeof(Service1)));
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
The problem is that all my links leads to the Service1.svc route now. #Html.ActionLink("Passport Maker", "Index", "Home", new { area = "" }, new { #class = "navbar-brand" }) become http://localhost:50099/Service1.svc?action=Index&controller=Home and other links change in the same way.
If I add ServiceRoute after "Default" route, the links work correctly but the service is unavailable.
Why it happens (there is no "Service1" in the links, why they select the service route then?) and how to fix it?
The solution:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { controller = "^(?!Service1.svc).*" }
);
routes.Add(new ServiceRoute("Service1.svc", new ServiceHostFactory(), typeof(Service1)));
Explanations for those who may encounter a similar problem: the reason of the problem was that Html.ActionLink uses the first matching route to generate the link. And my service route was the first and was matching, because a route does not require to include {controller} and {action} parameters to be matched (as I thought initially).
The solution is to put the default route first, so it is used by Html.ActionLink. And to still be able to use the service route, need to exclude it from the the first route using constraints. The regex ^(?!Service1.svc).* matches only those controller names that don't start from "Service1.svc".
there's
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
I want to make my url to allow enter company name in the beginning, e.g.:
url: "{company}/{controller}/{action}/{id}"
So I could navigate through pages and now that the base is some company.
domain.com/company-ltd
domain.com/company-ltd/products
domain.com/company-ltd/edit
domain.com/some-other-company-name-ltd/products
and so on.
How could I achieve this? Thanks.
The routes work off the back of patterns; a URL coming in is matched against patterns until one is found that it matches.
Assuming that you're not talking about optional company names, you should be able to get away with:
routes.MapRoute(
name: "Default With company",
url: "{company}/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional
);
and then simply ensure that all methods take a company parameter. However, this would fail on more simple routes, so make sure you set a default for pages such as the root. If you do end up wanting additional routes that don't involve a company, those can also be catered for with controller-specific routes:
routes.MapRoute(
name: "Profile",
url: "profile/{action}/{id}",
defaults: new { controller = "Profile", action = "Index", id = UrlParameter.Optional
);
before the less-specific company one.
Note that you can test these routes quite easily in .net using NUnit and MvcContrib.TestHelper, for example:
"~/company/".WithMethod(HttpVerbs.Get)
.ShouldMapTo<Controller.HomeController>(x =>
x.Index("company"));
"~/company/products/".WithMethod(HttpVerbs.Get)
.ShouldMapTo<Controller.ProductsController>(x =>
x.Index("company"));
to ensure that they're going to the locations you'd expect.
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!
I have a c# web api (.net 4) web application. I have several controllers. I'd like to map a new controller to the root directory for the web app.
So, I have http://localhost/listproducts
I'd like the url to be http://localhost
But I don't know how to tell the controller to use the root directory. It seems to be configured based on the name.
The solution I went with is:
config.Routes.MapHttpRoute(
name: "ListProductsApi",
routeTemplate: "",
defaults: new { controller = "ListProducts" } // Parameter defaults
);
The trick is the defaults: new { controller = "ListProducts" } line. (I need a POST action so I just left action out. Apparently when you want the root route "/" you need to explicitly name the controller.
You simply need to change the default route you already have. It should currently look something like this:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index",
id = UrlParameter.Optional }
);
Change controller = "Home" to controller = "listproducts".
It should be fairly easy, just change a default route in your global.asax.cs and instead of
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
change it to
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "ListProducts", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);