Here is my .Net MVC Folder structure:
I have a separate Folder called “Area” and inside that I have a Folder called “Restaurant”.
Inside this “Restaurant” Folder I have a controller Called “MenuController” which has action named “Index”
I am tried to rewrite the (Custom Route Mapping) url inside “Global.asax.cs” using following code.
routes.MapRoute(
"RestaurantMenu", // Route name
"Restaurant/{id}", // URL with parameters
new { controller = "/Restaurant/Menu", action = "Index", id = UrlParameter.Optional }
// Parameter defaults
);
But it gave me a HTTP 404 error.
The controller parameter inside your route should be the name of the controller, not the path :
If your controller name is Menu then, change it to this way :
routes.MapRoute(
"RestaurantMenu", // Route name
"Restaurant/{id}", // URL with parameters
new { controller = "Menu", action = "Index", id = UrlParameter.Optional }
// Parameter defaults
);
And the another strange thing is that : is this route sitting inside your Global.asax file? It should be inside your RestaurantAreaRegistration.cs file as follows;
public class RestaurantAreaRegistration : AreaRegistration {
public override string AreaName {
get {
return "Restaurant";
}
}
public override void RegisterArea(AreaRegistrationContext context) {
context.MapRoute(
"RestaurantMenu", // Route name
"Restaurant/{id}", // URL with parameters
new { controller = "Menu", action = "Index", id = UrlParameter.Optional }
// Parameter defaults
);
context.MapRoute(
"Accommodation_default",
"accomm/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
then you can give this a shot. If you would like to use ActionLink with this route, use it like that :
#Html.ActionLink("MyLink", "Index", "Menu", new { id = 1, Area = "Restaurant"})
I have written the above code with notepad so there might be some typos :)
Related
The below link gives be the following url: http://localhost:11111/files/Details/3
#Html.ActionLink("Details", "Details", "mycontroller", new { id = item.id },null)
But I'm trying to have a url parameter like this http://localhost:11111/files/Details?id=3 or http://localhost:11111/files/Details.aspx?id=3
How do I get the actionlink to show the url like details?i=3
Here is my controller View:
public ActionResult Details(int? id)
{
...
return View();
}
Why would you like to see the parameter's name in the link?
Asp.Net MVC uses user-friendly URLs.
If you have created a project in Visual Studio using the MVC template, probally your routes, by default, are configured to interpret the parameter after the controller/action/ like the id.
So the id parameter's value in your action will be automatically replaced, by model binding, with the id number present in you URL.
The routing codes can be found under the RegisterRoutes method in the Global.asax file of our project.
I see a cookie already in the RegisterRoutes method.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults);
Using the MapRoute method above, we defined a new route.
Sample ;
public class HaberController : Controller
{
public ActionResult Listele()
{
// Listing codes will be written
return View("Listele");
}
public ActionResult Detay(string HaberId)
{
// Detail codes will be written
return View("Detay");
}
}
We go to our Global.asax file and edit it as follows.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"HaberListeleme",
"Haber",
new { controller = "Haber", action = "Listele" }
);
routes.MapRoute(
"HaberDetay",
"Haber/{id}",
new { controller = "Haber", action = "Detay" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
If we do the routing as follows:
routes.MapRoute(
"HaberDetay",
"Haber/{*Id}",
new { controller = "Haber", action = "Detay" }
);
So if we write * by putting the character next to our parameter name, it will be sent to the related parameter of the Detail method in the Controller, no matter what it says after the News / url tab.
For example:
http://www.doguhanaydeniz.com/Haber/Turkiye/Guncel/34389
If a URL is requested as Turkey / current / 34389 will be sent as a parameter.
I have this route map defined.
routes.MapRoute("default", // route name
"{controller}/{action}/{id}", // url with parameters
new { controller = "home", action = "index", id = UrlParameter.Optional }, // parameter defaults
new string[] { "mobilesurveys.mt.controllers" }
);
This will work perfectly. now I want to add another routemap
routes.MapRoute("couponreedem", // route name
"{controller}/{action}/{clientname}", // url with parameters
new { controller = "Rc", action = "index", id = UrlParameter.Optional }, // parameter defaults
new string[] { "mobilesurveys.mt.controllers" }
);
i have defined like this. Here Rc is my controller. and I am giving the url as
.com /Rc/Rc/sammy
and method in the controller defined as
public ActionResult Rc(string clientname)
{
viewModel =dataRc.ProductCategoryGet();
return View(viewModel);
}
clientname will be always null. How to add another route while the existing route not be disturbed.
Thanks.
It actually looks identical. But in case you want a new one you can try something like this, and it should be above the default one.
routes.MapRoute("couponreedem", // route name
"RC/{action}/{clientname}", // url with parameters
new { controller = "Rc", action = "index", clientname = UrlParameter.Optional }, // parameter defaults
new string[] { "mobilesurveys.mt.controllers" }
);
That will fix the route with RC/...
Also your action should be named Index
public ActionResult Index (string clientname)
{
viewModel =dataRc.ProductCategoryGet();
return View(viewModel);
}
I'm kind of new to MVC. I have a controller called PostItemsController in an area called CaseManagers with an action method called GetByUmi(int caseNumber):
[HttpGet]
public ViewResult ViewByUmi(int umi)
{
//implementation omitted
}
The routing configuration looks like this (not my work):
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
//ignore route for ico files
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?../Images/MauriceFavicon.ico(/.*)?" });
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?Images/MauriceFavicon.ico(/.*)?" });
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?Content/Images/MauriceFavicon.ico(/.*)?" });
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?/favicon.ico(/.*)?" });
//ignore javascript files routing
routes.IgnoreRoute("{file}.js");
//ignore routing for files ending .doc
routes.IgnoreRoute("{resource}.doc");
routes.MapRoute(
"CaseManagers", // Route name
"CaseManagers/PostItems/ViewByUmi/{id}", // URL with parameters
new { controller = "PostItems" } // Parameter defaults
);
//InvoicesLookUp route
routes.MapRoute(
"InvoicesLookUpShortDefault", // Route name
"InvoicesLookUp/{action}/{id}", // URL with parameters
new { controller = "InvoicesLookUp", action = "Index", area = "Home", id = UrlParameter.Optional } // Parameter defaults
,
null,
new[] { "MooseMvc.Areas.Accounts.Controllers" } // Parameter defaults
).DataTokens.Add("area", "Accounts");
//Invoices route
routes.MapRoute(
"InvoicesShortDefault", // Route name
"Invoices/{action}/{id}", // URL with parameters
new { controller = "Invoices", action = "Index", area = "Accounts", id = UrlParameter.Optional } // Parameter defaults
,
null,
new[] { "MooseMvc.Areas.Accounts.Controllers" } // Parameter defaults
).DataTokens.Add("area", "Accounts");
//administrating route
routes.MapRoute(
"AdministratorShortDefault", // Route name
"Administrator/{action}/{id}", // URL with parameters
new { controller = "Administrator", action = "Index", area = "Administrator", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
//add root route route
routes.MapRoute(
"Root",
"",
new { controller = "Home", action = "Index", id = "" }
);
When I try to call this method with the URL http://localhost:[portnumber]/CaseManagers/PostItems/ViewByUmi/1234 I get the following exception:
The parameters dictionary contains a null entry for parameter 'umi' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ViewResult ViewByUmi(Int32)' in 'MooseMvc.Areas.CaseManagers.Controllers.PostItemsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
I don't intend the ID parameter to be optional and I don't understand why MVC can't find the ID.
Can anyone tell me what I need to do?
EDIT:
Phil Haack's route tester is telling me that the following route is being mapped:
routes.MapRoute(
"CaseManagers", // Route name
"CaseManagers/PostItems/ViewByUmi/{id}", // URL with parameters
new { controller = "PostItems" } // Parameter defaults
);
But it is being mapped AFTER another route CaseManagers/{controller}/{action}/{id}. But this route isn't anywhere in the Global.asax file (take a look, it's reproduced in full above).
Any idea what's going on?
Method parameters in ASP.NET MVC match up 1-1 with route parameters. Since you have no routes that take in a route value named umi, no route will catch what you're trying to do.
You have one of two choices:
If you want the default route to handle that action, then change:
public ViewResult ViewByUmi(int umi)
{
//implementation omitted
}
to:
public ViewResult ViewByUmi(int id)
{
//implementation omitted
}
However, if you want to keep umi(because it has contextual meaning that makes that code easier to follow), then you want to add a route to explicitly deal with it:
//UMI route
routes.MapRoute(
"umi",
"/case/postitems/view/{umi}",
new { area = "CaseManager", controller = "PostItems", action = "ViewByUmi", umi = "" }
);
Turns out that Global.asax isn't the only place that routing happens. Each of the areas in this application has its AreaRegistration class. I added a new route to the top of this class to produce the following:
public class CaseManagersAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "CaseManagers";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"PostItems", // Route name
"CaseManagers/PostItems/ViewByUmi/{umi}", // URL with parameters
new { area = "CaseManagers", controller = "PostItems", action = "GetByUmi", umi = "{umi}" } // Parameter defaults
);
context.MapRoute(
"CaseManagers_default",
"CaseManagers/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
The routing debugger now tells me this is getting matched first. Now I just need to work out why I've got an error telling the the resource cannot be found...
You don't have a route for CaseManagers/PostItems/ViewByUmi/1234 and it would appear that it is taking ViewByUmi and try to convert it to an System.Int32 because it is falling into the Default route. If you create a Route for your CaseManagers you should no longer have this problem.
Use Phil Haacks' Route Debugger to help you out :o)
routes.MapRoute(
"CaseManagers", // Route name
"CaseManagers/PostItems/ViewByUmi/{id}", // URL with parameters
new { controller = "PostItems" } // Parameter defaults
);
I have a url
http://www.roadkillwiki.org/Page/Index/documentation
which I want to turn into
http://www.roadkillwiki.org/Page/documentation
That could also be something like http://www.roadkillwiki.org/Page/my-url-with-spaces - the parameter is a string. The route setup I've tried is:
routes.MapRoute(
"ControllerDefault",
"{controller}/{id}",
new { controller = "Page", action = "Index", id = UrlParameter.Optional }
);
However this is interfering with the default "id" route that MVC projects come with. Is there any way of achieving this?
You don't need to lose the default route. The key to avoiding your routes interfere with each other is to order them so the more specific rules precede the less specific ones. For example:
// Your specialized route
routes.MapRoute(
"Page",
"Page/{slug}",
new { controller = "Page", action = "Index" }
);
// Default MVC route (fallback)
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
Then your PageController would look like this:
using System.Web.Mvc;
public class PageController : Controller
{
public string Index(string slug)
{
// find page by slug
}
}
That said, I would strongly advice you to do this instead:
// Your specialized route
routes.MapRoute(
"Page",
"Page/{id}/{slug}",
new { controller = "Page", action = "Index", slug = UrlParameter.Optional }
);
// MVC's default route (fallback)
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
And your PageController:
using System.Web.Mvc;
public class PageController : Controller
{
public string Index(int id)
{
// find page by ID
}
}
By including the page ID either at the beginning of your URL (like StackOverflow does) or at the end, you can then just ignore the slug, and instead retrieve your pages by ID. This will save you a ton of headaches if your users change the page name. I have gone through this and it's painful; you basically have to keep a record of all names your pages have had in the past, just so your visitors/search engines don't get a 404 every time a page is renamed.
Hope this helps.
If you don't need a default route that came with project template you can set up one like this:
routes.MapRoute(
"ControllerDefault",
"{controller}/{pagename}",
new { controller = "Page", action = "Index" }
);
And than in your controller you would have an action:
public ActionResult Index(string pagename)
{
//do something
}
I am new to ASP.Net MVC. May be this question looks simple, but i couldn't fix it. Here the scenario. I have an application listing data based on city. So the url will be looking like this
www.xxxxxx.in/chennai
www.xxxxxx.in/mumbai
www.xxxxxx.in/delhi
In normal routing the first part (chennai/mumbai) is controller in the above url, But here i dont want this to be a controller. instead i want to map the single controller (LocationController) to these URl's. Because later time i can add any number of city.
I am struck here, can someone help me out.
Try this:
routes.MapRoute(
"CityRoute", // Route name
"{city}", // URL with parameters
new { controller = "Location", action = "Index", city = "" } // Parameter defaults
);
I am not sure there won't be easier option than this, but you can try this - using route constraint. Basically, you need to know the list of cities you have and then constrain the route to match only entries in that list.
The route constraint can be implemented as follows
public class CityConstraint : IRouteConstraint
{
public static IList<string> CityNames = (Container.ResolveShared<ICityService>()).GetCities();
bool _IsCity;
public CityConstraint(bool IsCity)
{
_IsCity = IsCity;
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (_IsCity)
return CityNames.Contains(values[parameterName].ToString().ToLower());
else
return !CityNames.Contains(values[parameterName].ToString().ToLower());
}
}
And then put the route as follows:
routes.MapRoute("Location", "{cityName}", new { controller = "LocationController", action = "Index" }, new { cityName = new CityConstraint(true) });
Also make sure the above route is listed before the default route
routes.MapRoute("Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional
);
Also note that, no controller name can be a city name.
Try this and see.
If all your routing is related to these cities than remove default route and replace it with this route definition:
routes.MapRoute(
"Default",
"{city}",
new { controller = "Location", action = "Index", city = "Mumbai" }
);
Then create a LocationController class:
public class LocationController : Controller
{
public ActionResult Index(string city)
{
// do whatever needed; "city" param has the city specified in URL route
}
}
If you still need your default route (controller/action/id) for other pages not just cities then it's probably better to put a constraint on your default route and define them like this:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { controller = "Home|...|..." } // put all controllers here except "Location"
);
routes.MapRoute(
"Location",
"{city}",
new { controller = "Location", action = "Index", city = "Mumbai" }
);
This will make other controllers still working and location will work just as well. The problem is of course if there's a city name that's the same as a name of one of your regular controllers. :) But you can control/avoid that as well.
You can do that by adding a route that hardcodes the controller name:
routes.MapRoute(
"location", // Route name
"{cityName}", // URL with parameters
new { controller = "location", action = "index" } // Parameter defaults
);
routes.MapRoute(
"Location", // Route name
"{controller}/{action}/{cityName}", // URL with parameters
new { controller = "Location", action = "index"} // Parameter defaults
)
This will route all requests of the form "/mumbai" to LocationController action method Index with parameter cityName set to "mumbai". It will also be able to route full controller/action spec using the second route.