ASP.NET MVC 4: One controller routing is not like the others - asp.net-mvc-4

I have added a new controller, "LoggingController" to an MVC 4 application that already has several controllers.
Now I noticed that the routing behaviour for this controller is different from those that already existed.
For example, the following two urls work properly, as expected, and hit the "Index" method in BlogController.
http://localhost:56933/Blog/
http://localhost:56933/Blog/Index
So do all other controllers except the one I added:
http://localhost:56933/Logging/Index - works properly, hits the "Index" method in LoggingController
http://localhost:56933/Logging/ - returns "Server Error in '/' Application. The resource cannot be found."
Where should I start looking, beyond the obvious things?
Here is the Index signature from LoggingController
public ActionResult Index(int? page, string Period, string LoggerProviderName, string LogLevel, int? PageSize)
There is nothing specific to a certain controller in the MapRoute. Here is the full RouteConfig for reference:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
routes.MapRoute(
name: "Display",
url: "Post/{id}/{seofriendly}",
defaults: new { controller = "Post", action = "Display", id = UrlParameter.Optional, seofriendly = ""}
);
routes.MapRoute(
name: "SEOFriendly",
url: "{controller}/{action}/{id}/{seofriendly}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional, seofriendly = "" }
);
routes.MapRoute(
name: "SEOFriendlyNoId",
url: "{controller}/{action}/{seofriendly}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional, seofriendly = "" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}

Your Index method doesn't actually have a signature matched by any of your available routes. You'll have to either provide defaults to your Index action or add an additional route to the beginning of your route table to specify those defaults. For Example:
routes.MapRoute(
name: "LoggingDefaults",
url: "Logging/{Period}/{LoggerProviderName}/{LogLevel}/{page}/{PageSize}",
defaults: new {controller = "Logging",
action = "Index",
page = UrlParameter.Optional,
PageSize = UrlParameter.Optional,
LoggerProviderName = "SomeProvider",
Period = "SomePeriod",
LogLevel = "SomeLevel"}

Related

Mvc multiple "wildcard" route

I have a route using my kind of wildcard:
[Route("{category}/{subcategory?}/{property?}")]
public ActionResult SubPage(string category, string subcategory, string property, int? type)
{}
The problem is that I want to add another controller under an "Amp" folder
[Route("amp/{category}/{subcategory?}/{property?}")]
public ActionResult Amp(string category, string subcategory, string subSubCategory)
{}
My router looks like this:
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Amp",
url: "amp/{controller}/{action}/{id}",
defaults: new { controller = "Amp", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
This doesn’t work if the url is /amp/category1 due to that the url structure match both url's

ASP.Net Routing: Customer ID not passing to action

see my url localhost:55831/Customers/Edit/1/ALFKI which i generate using #Html.RouteLink
#Html.RouteLink("Edit", "PageWithId",
new
{
controller = "Customers",
action = "Edit",
id = item.CustomerID,
page = ViewBag.CurrentPage
})
here is my routing code for PageWithId i tried two routing one after one but none work
routes.MapRoute(
name: "PageWithId",
url: "{controller}/{action}/{page}/{id}"
);
AND
routes.MapRoute(
name: "CustomerEditWithId",
url: "Customers/Edit/{page}/{id}",
defaults: new { controller = "Customers", action = "Edit" }
);
my all routing code
routes.MapRoute(
name: "PageWithSort",
url: "{controller}/{action}/{page}/{SortColumn}/{CurrentSort}",
defaults: new { action = "Index", page = UrlParameter.Optional, SortColumn = UrlParameter.Optional, CurrentSort = UrlParameter.Optional }
);
routes.MapRoute(
name: "PageWithId",
url: "{controller}/{action}/{page}/{id}"
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
please some one help because when i am clicking ob this link localhost:55831/Customers/Edit/1/ALFKI then customer id ALFKI is not passing to edit action. i debug the edit action code and found id is getting null always. i tried few routing for edit action but no luck still.
The order of routes matters. Routes are checked in order and the first matching route wins.
Because your first (PageWithSort) route matches any route with between 1 and 5 segments, then /Customers/Edit/1/ALFKI, which contains 4 segments matches, and no further routes are checked. And since ALFKI is being passed to the 4th segment named SortColumn, then it will only be bound to a parameter named SortColumn in your Edit() method (not to something named id)
As it stands, your PageWithId and Default routes are pointless since they can never be hit.
In additional, only the last parameter in a route definition can be marked with UrlParameter.Optional.
You need to create specific routes, and locate them in the correct order. Change your route definitions to (note I have omitted the PageWithSort route because its not clear what you want to do with that and it contains errors anyway)
routes.MapRoute(
name: "CustomerEditWithId",
url: "Customers/Edit/{page}/{id}",
defaults: new { controller = "Customers", action = "Edit" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Now any url that begins with /Customers/Edit and contains 2 additional segments will match the CustomerEditWithId route, and the 3rd segment will be bound to a parameter named page and the 4th segment will be bound to a parameter named id. Therefore your method in CustomersController should be
public ActionResult Edit(int page, string id)

Remove action name as well as parameters in Asp.Net MVC 4 route

This is my action method.
public ActionResult Edit(string courseName, int id = 0)
{}
Routes defined in config file are
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Course",
url: "{Course}/{Edit}/{courseName}/{id}",
defaults: new { controller = "Course", action = "Edit", courseName = UrlParameter.Optional, id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Course", action = "Index", id = UrlParameter.Optional }
);
}
It is working fine.
My url looks like - /Course/Edit/Androi/1
I want it to look like - /Course/Androi
I dont want to use the Index method and I don't want to show the Id.

MVC 4: Custom Routes

I see a lot of problems with MVC routes and I'm having a similar problem getting a route to match a URL.
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//default route
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute("Beer", "Beer/{beerid}", new { controller = "Beer", action = "Id", beerid = 0});
routes.MapRoute("Beer", "Beer/{beername}", new { controller = "Beer", action = "Name" });
BeerController Methods
public ActionResult Id(int beerid)
public ActionResult Name(string beername)
If I change the methods to the following,
public ActionResult Id(int? id)
public ActionResult Name(string id)
the default routing works with the following URLs:
http://localhost/Beer/Id/100
http://localhost/Beer/Name/Coors
But what I'm going for is just
http://localhost/Beer/100
http://localhost/Beer/Coors
Any ideas?
So a couple things here.
More specific routes should be placed before more general routes, because the first route that is matched will be used and routes are inspected in the order they are added.
If you plan on not providing the name of the action in your URL then you will need to do something to ensure the correct route is targeted so the correct default value will be used. In your case you could use a route constraint to distinguish between the two. Try changing your beer id route to this:
routes.MapRoute(
name: "Beer",
url: "Beer/{beerid}",
defaults: new { controller = "Beer", action = "Id", beerid = 0},
constraints: new { beerid = #"\d+" }
);
The constraint will ensure that the route only matches two-segment URLs where the second segment is composed of one or more digits. This route as well as your route for beer name should be placed before the default route.
UPDATE
My configuration seems to be yielding the results you want. The entirety of my RegisterRoutes method is as follows:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Id",
url: "Beer/{beerid}",
defaults: new { controller = "Beer", action = "Id", beerid = 0 },
constraints: new { beerid = #"\d+" }
);
routes.MapRoute(
name: "Name",
url: "Beer/{beername}",
defaults: new { controller = "Beer", action = "Name" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

MVC4 Route with Id and Index Action

I'm trying to accomplish the following and receiving the "resource not found" error for #2. Assuming because the routing is not configured correctly.
Desired URLs:
1) domain.com/Customer
2) domain.com/Customer/1 *Does Not Work
3) domain.com/Customer/All
public ActionResult Index(int? id)
{
var viewModel = new CustomerViewModel();
if (!id.HasValue)
id = 1; // ToDo: Current Logged In Customer Id
viewModel.Load(id.Value);
return View(viewModel);
}
public ActionResult All()
{
return View(CustomerModel.All());
}
My Route Config has the default route setup and I've tried adding an additional route to no avail.
routes.MapRoute(
name: "Customer",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Customer", action = "Index", id = UrlParameter.Optional }
);
I've excluded my attempts at setting up a new route since it doesn't work.
Your route would normalize out to domain.com/Customer/Index/1. When you have subsequent parts of the route, you can't eliminate an earlier component just because its value will be the default. In this case, it's looking for an action named "1" which it can't find.
Edit:
If your desired route is domain.com/Customer/ID, then you can add such a route to your route table:
routes.MapRoute(
name: "CustomerAll",
url: "Customer/All",
defaults: new { controller = "Customer", action = "All" }
);
routes.MapRoute(
name: "CustomerByID",
url: "Customer/{id}",
defaults: new { controller = "Customer", action = "Index" }
);
These more-specific routes should come before your default route.
try to add this route before the default one
routes.MapRoute(
name: "Customer",
url: "Customers/{id}",
defaults: new { controller = "Customer", action = "Index", id = UrlParameter.Optional }
);
and note that the url starts with Customers not Customer.
and your desired URL will be : domain.com/Customers/1 instead of domain.com/Customer/1