I am using conventional routing on an ASP.Net MVC project and would like to enable Attribute routing in parallel. I have created the following but I am getting a 404 on the conventional route when enabling attribute routing
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Controller
[RoutePrefix("Registration")]
public class RegistrationController : Controller
{
[HttpGet]
[Route("Add/{eventId}")]
public ActionResult Add(int eventId)
{
}
}
Calling
http://localhost/Registration/Add/1
Works, while calling
http://localhost/Registration/Add?eventId=1
No longer works and responds with 404 NotFound
Should work if you make the {eventId} template parameter optional in the route template
[RoutePrefix("Registration")]
public class RegistrationController : Controller {
//GET Registration/Add/1
//GET Registration/Add?eventId=1
[HttpGet]
[Route("Add/{eventId:int?}")]
public ActionResult Add(int eventId) {
//...
}
}
The reason the two were not working is that the route template Add/{eventId} means that the route will only match if the {eventId} is present, which is why
http://localhost/Registration/Add/1
works.
By making it (eventId) optional eventid? it will allow
http://localhost/Registration/Add
to work as the template parameter is not required. This will now allow query string ?eventId=1 to be used, which the routing table will use to match the int eventId parameter argument on the action.
http://localhost/Registration/Add?eventId=1
I also got this issue. Which MVC version are you using?
I faced this issue with MVC in asp.net core.
I think this is a flaw as if you provide Routing attribute on any action method, its conventional route is over ridden and is not longer available so you get 404 error.
For this to work, you can provide another Route attribute to your action method like this. This will work
[Route("Add/{eventId}")]
[Route("Add")]
Related
I'm trying to get a handle on attribute routing in MVC.
Initially, the routing for my sitemap controller was as follows:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "SitemapXml",
url: "sitemap.xml",
defaults: new { controller = "Sitemap", action = "Index" }
// Additional mappings...
}
}
That works fine. But then I tried commenting out the SitemapXml routing above and instead adding an attribute in my controller.
// GET: Sitemap
[Route("sitemap.xml")]
public ActionResult Index()
{
// Generate sitemap
}
I also added the following line at the end of RegisterRoutes:
routes.MapMvcAttributeRoutes();
But now when I navigate to domain.com/sitemap.xml, I get a page not found error.
Questions:
What steps am I missing to get my routing attribute to work?
Since mappings can now be specified in two places (as attributes or set directly in the RouteCollection), what happens when those two places contradict each other?
if you remove the extension .xml , your attribute routing will work perfectly. And its better to use the extension related code in action method.
Also make sure your route config looke like (routes.MapMvcAttributeRoutes(); should exist before default route)
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Account", action = "Login", id = UrlParameter.Optional }
);
I´m trying to set up a route in MVC so that when POSTing to the following url
/organizations/55/repositories
I get all the repositories for organization 55
I've tried using the following route but to no avail, it never reaches the controller action method
[Route("/organizations/{id}/repositories")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Repositories(long id, OrganizationSearchParametersDTO parameters)
However if I do it in the RegisterRoutes method, it works:
routes.MapRoute("OrganizationControllerRoute", "organizations/{id}/repositories", new {controller = "Organizations", action = "Repositories"});
But I'd prefer to have it running using attributes because it's our way to work
What am I doing wrong, any ideas?
If your routes.MapRoute(..) definition works, but not the [Route(...)] attribute, it means that you have not enabled attribute routing in the RouteConfig.cs file
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Add the following line before any route definitions
routes.MapMvcAttributeRoutes();
... // add routes.MapRoute(...) definitions as required
}
}
This question already has answers here:
Routing in ASP.NET MVC, showing username in URL
(2 answers)
Closed 4 years ago.
I am new to C# MVC,
This is my default RouteConfig File,
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 }
);
}
}
When I run my project http://localhost:50382 it redirects the default home index method.
How can I build custom url like http://localhost:50382/somestringcode and call a specific ActionMethod. Something Like a custom route that points to specific ActionMethod and the stringcode will be passed as parameter.
public ActionResult Method1( string code)
{
return View();
}
What you are searching for is attribute routing. That means specifying URL routes explicitly.
First, you need to enable it
routes.MapMvcAttributeRoutes();
Then add Route attribute to desired action:
[Route("")]
public ActionResult Method1( string code)
{
return View();
}
Since code parameter is simple type, it will be searched in request URL.
You need to do something like this, where controller1 is the controller name that contains Method1, and make sure you place this first, and leave the original route config, so when it doesn't match this route, it will use default route.
Please note this is bad practice, and it will fail in case route is trying to access default action for a controller "Index" as #stephen mentioned in the comments below, and that's why I would suggest adding a prefix ex "Action1" to the route.
routes.MapRoute
(
name: "Method1",
url: "Action1/{code}",
defaults: new { controller = "controller1", action = "Method1", code = "default"}
);
I made a website using asp.net webforms. It uses the default route which is url friendly. Can I set a custom route for some pages by assigning it to global.asax without affecting all other pages route?
By default MVC uses the conventional routing which uses something of this sort.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Which translates to http://localhost:9999/<controllerName>/<ActionName>/<OptionalIDs>
But if you want custom routes its possible in ASP.NET MVC 5 this feature is called Attribute Routing, if you are using Visual Studio 2015 or above.
For example:
Adding the following line to your global.asax.cs file will enable attribute routing in your MVC 5 application:
routes.MapMvcAttributeRoutes();
This will be rendered as http://localhost:9999
[HttpGet]
[Route(Name = "HomeView")]
public ActionResult Index()
{
return View();
}
This will be rendered as http://localhost:9999/Login
[HttpGet]
[Route("~/Login", Name = "LoginGET")]
public ActionResult Login()
{
return View();
}
In your view you can use the Html.BeginRouteForm("<RouteName>", FormMethod.Post) helper method for handling routes.
[HttpPost]
[Route("~/Login", Name = "LoginPOST")]
public ActionResult Login(FormCollection UserCredentials)
{
//do stuff
return RedirectToRoute("HomeView");
}
For referring MVC Actions via Routes in _layout.html you can use:
Html.RouteLink("Link text that you want to display in the view", "<RouteName>");
For More information you can always check MSDN Attribute Routing.
I am developing a website on Azure, with mvc5. I use attribute routing, with routes and route prefix on controllers. I call with action.link helper. I did not name my routes.
I did the following on my route.config:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.LowercaseUrls = true;
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
My controllers are like:
[OutputCache(Duration = 600, Location = System.Web.UI.OutputCacheLocation.Client)]
[RoutePrefix("istanbul/kadikoy")]
[Route("{action=index}")]
public class KadikoyController : Controller
{
public ActionResult Index()
{
return View();
}
[Route("kadikoy-tarihi")]
public ActionResult KadikoyTarihi()
I have very very poor performance as server response time, i.e. 9.6s
If I comment out the attribute route codes, with default routing, I have 2.1 s server response time.
Thank you for your replies.
It turns out that the really expensive bit of this operation isn't mapping your attributed routes, it's that before that can happen MVC needs to create the ControllerFactory and retrieve all the Controller types. That process accounts for 1245 ms in my project, while the rest of the MapMvcAttributeRoutes() functions take about 45ms. My guess is that if you don't use the attribute routing the controllers are found as needed rather than all at once.