Regarding Route.config file and attribute routing ASP.Net MVC - asp.net-mvc

We know route is register in route.config file like below
routes.MapRoute(
name: "ProductPage",
url: "{productId}/{productTitle}",
defaults: new { controller = "Products", action = "Show" },
constraints: new { productId = "\\d+" }
);
Can we delete routing related code from route config file and implement attribute routing instead?
See this
[Route("{productId:int}/{productTitle}")]
public ActionResult Show(int productId) { ... }
Can we use the above attribute routing instead?
Can we delete all routing related code from route config file, so my route config would look like?
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
}
}
Please help me to have control over this routing issue. Thanks

You certainly can, but it's better to keep one default route in RouteConfig and add decorate other action methods with route attributes.

Related

How do I make a scaffolded page the first page

So I'm following the get started tutorial on ASP.NET . So far so good, however going to /controllerName is quite tedious. Is there a way how I can go to that index page on start up of the project? I couldn't find it in the walkthrough or any documentation. I'm using version 6.0 . I'm sorry for this basic question.
.NET MVC has built in defaults that can be overriden.
The default start page which will be routed from the root / is the Index action on the home controller:
public class HomeController :
{
public IActionResult Index()
{
// ...
}
}
Sticking to these defaults is a good idea so other developers will find it easier to make sense of your project.
But you can override the defaults in .NET 5.0 if you wish in the Startup.cs Configure method:
app.UseEndpoints(routes =>
{
routes.MapControllerRoute(
name: "default",
pattern: "{controller=MyDefaultController}/{action=MyDefaultActionMethod}/{id?}");
});
}
You can change the desired starting page from Route config. It's in
App_Start>RouteConfig
route config
You can change it controller name and index page as you want.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controllerName}/{actionName}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}

Attribute Routing over Convention-based Routing in MVC, which one would be called first?

I am assuming that the convention routing would be added to the route table first because it is getting registered in the global.asax file like this
RouteConfig.RegisterRoutes(RouteTable.Routes);
Now I have a route like this in the route.config
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapMvcAttributeRoutes();
}
and I have an attribute route like this
[Route("students/{id?}")]
public ActionResult Index(int? id)
{
return View(id);
}
Now when I use the URL
localhost:4200//students
The students route is getting called successfully but when I use the route like this
localhost:4200//students/40
I get error, I don't know the reason why. When I remove the route from RouteConfig class I am able to call it successfully.
Can anyone explain me why and how?
In your original example the URL localhost:4200//students/40 is being matched to the url: "{controller}/{action}/{id}", convention-based route template.
But since there is no action called 40 it will fail.
Now because it has already matched a route, it will not check any further for other matches so you will end up with Not Found error.
In Asp.Net MVC, routes are called in the order they are added to the routing table. First match wins and it does not do any further checks.
Targeted attribute routes are usually added before more general convention based routes to avoid route conflicts like the one experienced in your example.
public static void RegisterRoutes(RouteCollection routes) {
//Attribute routes
routes.MapMvcAttributeRoutes();
//Convention-based routes.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}

MVC5 attribute routing equivalent of route.config route

Say I have the following in my route.config
public static void RegisterRoutes(RouteCollection routes)
{
if (routes != null)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(name: "category", url: "{category}", defaults: new { controller = "Category", action = "Index" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
How do I do the equivalent of my category route using a routing attributes?
I have tried the following:
[Route("{action=Index}")]
public class CategoryController : Controller
{
[Route("{category}")]
public ActionResult Index(string category)
{
return View(category);
}
}
But this the throws up an error:
Multiple controller types were found that match the URL. This can happen if attribute routes on multiple controllers match the requested URL.
Is it possible or do I need to leave this one in the route.config?
It looks like you are currently not able to do the above with attribute routing only as the only ordering I was able to find was to order the action routes within the controller itself:
[Route("{category}", Name = "Category", Order = 1)]
But this won't help with multiple controller types error. Having done a lot more research about Attribute Routing vs Convention Routing, a lot of the blogs and answers I have come across state that it is probably best to use both types together as certain situations may warrant one or the other.
I think in my case as the order of that route and controller are important, then it is best to use conventional routing for it to make sure it comes at the end (but before the default catch all)

How can I get my asp.net MVC routing to use a default action within a sub-folder?

I have an ASP.Net MVC app where I need to place a certain section of code in a sub-folder named web.
I would like for the user to be able to simply type "http://www.mywebsite.com/web/mycontroller" and have it default to the action of index.
However, I can't seem to figure out how to set up my routing to default the action. From what I can tell, it's trying to use the controller = web, action = mycontroller.
My route code looks like this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"web", "web/{controller}/{action}",
new { action = "Index" });
}
The request works fine as long as I include the /index on the end of my URL, but it doesn't seem to want to use the action = "Index" default if I exclude it.
How can I accomplish this?
Change your code as follows:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "web",
url: "web/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
I ended up using Areas, and this has fixed my problem.

ASP.Net MVC Redirect Specific Routes to External Site

I have an nicely functioning ASP.Net MVC site using the simple standard routing scheme:
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
My client would like to redirect the static pages to a secondary site, so that they can edit them, template-style, at will. The pages that actually do something will remain on the original site.
What I need to do is set up routes for my functional views/controller-actions and redirect the remaining urls to the external site regardless of whether or not the specified url has a matching controller/action. I don't want to mess with the existing code, but use routing to execute some of the pages and redirect from others.
For example:
mysite.com/sponsors/signup would be executed
mysite.com/sponsors/information would be redirected
Even though the sponsors controller contains actions for both signup and information and there are existing views for both signup and information.
So far, I have been unable to wrap my head around a way to do this.
Any ideas?
You can use attribute routing to make it easier.
Your RouteConfig will look like below:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes(); // enable attribute routing
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
}
}
Then you can add an action like below:
public class SponsorsController : Controller
{
[Route("sponsors/information")]
public ActionResult RedirectInformation()
{
return RedirectPermanent("http://yoururl.com");
}
}
EDIT ONE
If you don't want to use attribute routing, you are still going to need the action but your RouteConfig will look like below:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//The order is important here
routes.MapRoute(
name: "redirectRoute",
url: "sponsors/information",
defaults: new { controller = "Home", action = "RedirectToInformation"}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
In routing like this, if the match is found the rest of the routes are ignored. So, you'd want to put most specific route on top and most general in the bottom
EDIT TWO (based on the comment)
You can put a simple appsettings in Web.config like below:
<appSettings>
<add key="UseAttributeRouting" value="true" />
</appSettings>
Then in RegisterRoutes you can read it like below and make the decision.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
if (Convert.ToBoolean(ConfigurationManager.AppSettings["UseAttributeRouting"]))
{
routes.MapMvcAttributeRoutes();
}
else
{
routes.MapRoute(
name: "redirectRoute",
url: "sponsors/information",
defaults: new {controller = "Home", action = "RedirectToInformation"}
);
}
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
The browser sometimes caches these redirects, so you may want to recommend clearing browser caches if you change these settings. Check this superuser post for clearing the cache for Chrome.
You have two options
i) This is perfect use case to write a custom mvchandler that is instatiated by a custom IRoutehandler. You can follow this example.
http://www.eworldui.net/blog/post/2008/04/aspnet-mvc---legacy-url-routing.aspx.
ii) You can write HttpHandler for these matching paths you can redirect them to the other site.
Step 1: add this to RouteConfig.cs
routes.IgnoreRoute("yourwebpage.aspx");
Step 2: create new file at root of website called "yourwebpage.aspx"
Step3: Inside yourwebpage.aspx put:
<%
Response.RedirectPermanent("http://yourwebsite.com");
%>
It is pretty simple.
Create an Action
public ActionResult ext(string s)
{
return Redirect(s);
}
And in Routeconfig file add
routes.MapRoute(name: "Default17", url: "routeyouwant", defaults: new { controller = "Home", action = "ext", s = "http://externalurl.com" });

Resources