My Booking Controller have the following code
public ActionResult Index(string id, string name)
{
return View();
}
and my routeConfig have the below route mappings
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: "Search",
url: "{controller}/{location}/{checkIn}/{checkOut}/{no}",
defaults: new { controller = "Search", action = "Index", location = UrlParameter.Optional, checkIn = UrlParameter.Optional, checkOut = UrlParameter.Optional, no = UrlParameter.Optional }
);
routes.MapRoute(
name: "booking",
url: "{controller}/{action}/{id}/{name}",
defaults: new { controller = "Booking", action = "Index", id = UrlParameter.Optional, name=UrlParameter.Optional }
);}
but when I access the page http://localhost:59041/booking/index/1/libin both params returns null.
see this book
As your application becomes more complex you are likely going to
register multiple routes. When you do this its important that you
consider the order that that you register them. When the routing
engine attempts to locate a matching route, it simply enumerates the
collection of routes and it stops enumerating as soon as it find a
match.
Add a comment This can cause plenty of problems if you’re not
expecting it. Let’s look at an examples where this can be a problem:
routes.MapRoute(
> "generic", // Route name
> "{site}", // URL with parameters
> new { controller = "SiteBuilder", action = "Index" } // Parameter defaults );
>
> routes.MapRoute(
> "admin", // Route name
> "Admin", // URL with parameters
> new { controller = "Admin", action = "Index" } // Parameter defaults );
The snippet above registers two routes. The first route
contains a single placeholder segment and sets the default value of
the controller parameter to SiteBuilder. The second route contains a
single constant segment and sets the default value of the controller
parameter to Admin.
Both of these routes are completely valid, but the order in which they
are mapped may cause unexpected problems because the first route
matches just about any value entered, which means that it will be the
first to match
http://example.com/Admin and since the routing engine stops after
finding the first match, the second route would never get used.
So, be sure to keep this scenario in mind and consider the order in
which you define custom routes.
You should write booking routes at first
routes.MapRoute(
name: "booking",
url: "{controller}/{action}/{id}/{name}",
defaults: new { controller = "Booking", action = "Index", id = UrlParameter.Optional, name=UrlParameter.Optional }
);}
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: "Search",
url: "{controller}/{location}/{checkIn}/{checkOut}/{no}",
defaults: new { controller = "Search", action = "Index", location = UrlParameter.Optional, checkIn = UrlParameter.Optional, checkOut = UrlParameter.Optional, no = UrlParameter.Optional }
);
Related
Check the RouteConfig.cs file code bellow on mvc5 project. The first Default route which is configured for return home page is works fine. But the second one which i made to send traffic to Product controller is not working. The way i am trying to hit the controller is- http://localhost:50070/Product/somepage/good-product
The error i am getting is:
The resource cannot be found.
public class RouteConfig
{
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: "Product",
url: "Product/{pagename}/{slug}",
defaults: new { controller = "Product", action = "Index", slug = UrlParameter.Optional },
namespaces: new[] { "Demo.Controllers" }
);
}
}
You problem is in order of route mappings. Routes are matched in mapping order - in your case Product/somepage/good-product matches default route template and it is chosen. But you don't have action Somepage on Product controller.
Default route mapping should be the last mapping (just change the order):
routes.MapRoute(
name: "Product",
url: "Product/{pagename}/{slug}",
defaults: new { controller = "Product", action = "Index", slug = UrlParameter.Optional },
namespaces: new[] { "Demo.Controllers" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Please change second routes like that
Use controller in order to pagename
routes.MapRoute(
name: "Product",
url: "Product/{controller}/{slug}",
defaults: new { controller = "Product", action = "Index", slug = UrlParameter.Optional },
namespaces: new[] { "Demo.Controllers" }
);
The current Route Config for me is this, which I think is the default one
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
When I write
www.mypage.com
www.mypage.com/home
I get the same page
How Can I make it so that they are two individual pages
www.mypage.com
is the homepage, and
www.mypage.com/home
is another page
www.mypage.com can be handler by a root controller and all the other routes will be handled by the default route.
routes.MapRoute(
name: "Root",
url: "",
defaults: new {controller = "Root", action = "Index"}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { action = "Index", id = UrlParameter.Optional }
);
the explicit defaults allow for the behavior you are currently seeing.
You will still need to create a controller to handle your root site calls
public class RootController : Controller {
public ActionResult Index() {
return View();
}
}
And don't forget to create the related View for your controller.
No need to create a new controller. you can use the same home controller. In Home Controller, create 2 actions - Default and Index. In the routeconfig, use -
routes.MapRoute(
name: "RootDef",
url: "",
defaults: new { controller = "Home", action = "Default", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
I'm coding a website like a platform where we can access the user profile from the following URL:
www.mywebsite.com/DanielVC
The controller that has the details about the profile is the following
Controller: Perfil
Action: Perfil
I already have the following Route for all application:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Pages", action = "Index", id = UrlParameter.Optional }
);
I already tried to create the following route:
routes.MapRoute(
name: "Perfil",
url: "Pages/{id}",
defaults: new { controller = "Pages", action = "Index", id = UrlParameter.Optional }
);
But didn't work
Put this BEFORE (above) the default route.
routes.MapRoute(
name: "Perfil",
url: "{id}",
defaults: new { controller = "Pages", action = "Index", id = UrlParameter.Optional }
);
Also, this will result in every route to be redirected to Perfil route. You must create a redirection in that action if a username is not found (e.g. mywebsite.com/randomuserthatdoesntexist) and/or other routes (mywebsite.com/contact).
EDIT
Example for your method
public class PagesController : Controller
{
public ActionResult Index(string id)
{
if (matchesOtherRoute(id))
RedirectToAction("OtherAction", "OtherController");
if (!userExists(id))
RedirectToAction("NotFoundAction", "ErrorController");
// Do other stuff here
}
}
it should be like
routes.MapRoute(
name: "Perfil",
url: "Pages/{id}",
defaults: new { controller = "Perfil", action = "Perfil", id = UrlParameter.Optional }
);
For www.demo.com/city/hotel-in-city
routes.MapRoute(
name: "Search",
url: "{city}/{slug}",
defaults: new { controller = "Demo", action = "Index", city = UrlParameter.Optional}
);
For default
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
But when I call the index method of home controller www.demo.com/home/index it points to 1st route(index method of default controller).
How to handle default route ?
The problem is that your "Search" route captures basically everything. One way of handling this is to create more-specific routes for the home controller, and put those first:
routes.MapRoute(
name: "Home1",
url: "/",
defaults: new { action = "Index", controller = "Home" }
);
routes.MapRoute(
name: "Home2",
url: "Home/{action}/{id}",
defaults: new { id = UrlParameter.Optional, action = "Index", controller = "Home" }
);
routes.MapRoute(
name: "Search",
url: "{city}/{slug}",
defaults: new { controller = "Demo", action = "Index" }
);
This will filter out any URL with "Home" as the first parameter, and allow everything else through to the search.
If you have a lot of controllers, the above approach may be inconvenient. In that case, you could consider using a custom constraint to filter out either the default route, or the "Search" route, whichever one you decide to put first in the route config.
For example, the following constraint declares the match invalid, in case the routing engine has attempted to assign "Home" to the "city" parameter. You can modify this as needed, to check against all your controllers, or alternately, against a cached list of available city names:
public class SearchRouteConstraint : IRouteConstraint
{
private const string ControllerName = "Home";
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
return String.Compare(values["city"].ToString(), ControllerName, true) != 0;
}
}
This will allow URLs starting with "/Home" through to the default route:
routes.MapRoute(
name: "Search",
url: "{city}/{slug}",
defaults: new { controller = "Demo", action = "Index" },
constraints: new { city = new SearchRouteConstraint() }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { id = UrlParameter.Optional, action = "Index", controller = "Home" }
);
I have 2 routes
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Plugin",
url: "{pluginName}/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
I would like to use Html.Action helper and set "pluginName" parameter of my second Route.
I am try to use next code
#Html.Action("Index","Person",new RouteValueDictionary { { "pluginName", "myPlugin" } });
and to get link like
http://mydomain/myplugin/Person/index
but I've getting
http://mydomain/Person/index?pluginName="myPlugin"
How can I get first link pattern?
Register your more specific route first. The routing engine evaluates routes in the order you register them. So if you have a fairly generic route registered early on (which you do), the routing engine will use it and append other values as QueryString parameters (which your seeing).
Try this:
routes.MapRoute(
name: "Plugin",
url: "{pluginName}/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);