Change Controller Route in ASP.NET Core - c#

So I have a HomeController, to access it along with Actions I have to type url.com/home/action.
Would it be possible to change this to something else like url.com/anothernamethatpointstohomeactually/action?

I suggest you to use attribute routing, but of course it depends on your scenario.
[Route("prefix")]
public class Home : Controller {
[HttpGet("name")]
public IActionResult Index() {
}
}
This will be found at url.com/prefix/name
There are a lot of options to attribute routing, some samples:
[Route("[controller]")] // there are placeholders for common patterns
as [area], [controller], [action], etc.
[HttpGet("")] // empty is valid. url.com/prefix
[Route("")] // empty is valid. url.com/
[HttpGet("/otherprefix/name")] // starting with / won't use the route prefix
[HttpGet("name/{id}")]
public IActionResult Index(int id){ ... // id will bind from route param.
[HttpGet("{id:int:required}")] // you can add some simple matching rules too.
Check Attribute Routing official docs

You can add new Routes in your Startup.Configure method within your app.UseMvc(routes => block:
routes.MapRoute(
name: "SomeDescriptiveName",
template: "AnotherNameThatPointsToHome/{action=Index}/{id?}",
defaults: new { controller = "Home"}
);
The code is quite similar to ASP.NET MVC.
For more info, see Routing in ASP.NET Core.
Below is for ASP.NET MVC (not ASP.NET Core MVC)
You can also add a new Route via routes.MapRoute in your RouteConfig:
routes.MapRoute(
name: "SomeDescriptiveName",
url: "AnotherNameThatPointsToHome/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Make sure, you insert the code before you define your Default route.
For more information, visit the docs.

Using the Route attribute on top of your controller will allow you to define the route on the entire controller.
[Route("anothernamethatpointstohomeactually")]
You can read more here.

In ASP.NET Core 6, we just do that in one line.
Go to your Controller and write before your action method:
[Route("YourController/YourAction/{YourParameter?}")]
In your example, you you need to write like this:
[Route("Home/Index/{name?}")]

You can change your url by modifying your routing configuration.
It is kind of like htaccess but not really.
https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/controllers-and-routing/creating-custom-routes-cs
Another solution is to create a page and do a server redirect.
Server.Transfer

Related

ASP.NET Core MVC Subaction in a controller

I have an Administration Controller with a Users method. And I would like to add a “new” Subaction with a new View to this method. The URL should look like this: /administration/users/new
How can I do that?
Thanks for your help!
This is really just a question about routing. Just add a method in the Administration controller and tell MVC what the route is with a Route attribute. For example:
public class AdministrationController : Controller
{
public ActionResult Users()
{
}
[Route("users/new")] //This is the important part here
public ActionResult NewUser()
{
}
}
You could also configure the routing inside your Startup.cs class, but I find it easier to do with attribute routing. See here for more information.
I guess what you mean is "Area".
So, in Asp.Net Core 2 routing, there are areas, there are controllers, there are actions and optionally parameters.
You can have routing middleware configured something like. You can specify area attribute on the contorllers.
Administrator would be area - Users would be controller and New would be action.
This should keep the code clean as this is merely using the default routing middleware.
For better understanding of Areas, please refer: https://tahirnaushad.com/2017/08/25/asp-net-core-2-0-mvc-areas/
app.UseMvc(routes =>
{
routes.MapRoute(
name: "areaRoute",
template: "{area:exists}/{controller=dashboard}/{action=index}/{id?}"
);
routes.MapRoute(
name: "default",
template: "{controller=home}/{action=index}/{id?}"
);
You can use several methods to do it
Routes at .net core
try attributes
[Route("users/new")]
public IActionResult New()
{
return View();
}

Generate URL Without Index Using Tag Helpers

I have an action link that looks like this
<a asp-controller="Complaint" asp-action="Index" asp-route-id="#complaint.Id">
This will then generate the link /Complaints/Index/be8cd27e-937f-4b7d-9004-e6894d1eebea
I'd like the link to not have Index. I've tried to add a new route to Startup but with no success.
routes.MapRoute(
"defaultNoAction",
"{controller=Complaint}/{action=Index}/{id}");
I can't find any documentation to see if it's possible to generate the URL with tag helpers without Index. Perhaps someone here knows how?
Decorate your controller's action with a route attribute that would have the route you need.
[Route("Complaints/{id}")]
public IActionResult Index(string id)
{
return View();
}
This way your controller's action becomes the default one. Please make sure other methods have different signature.
UPDATE
To set up routing in Startup class it's important to define the order of routing rules correctly. Per ASP.NET Routing Documentation:
The route collection is processed in order. Requests look for a match in the
route collection by URL matching. Responses use routing to generate
URLs.
This means your specific rules should go first, and the default route template should go afterwards like a catch-all rule. In your case the following should do the trick.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "complaints",
template: "complaints/{id}",
defaults: new { controller = "Complaints", action = "Index" });
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});

What's the difference between configuration-based routing and attribute routing in MVC?

I have used the most conventional way to build routes:
routes.MapRoute(
name: "Client",
url: "{controller}/{id}",
defaults: new { controller = "Client", action = "Index", id = UrlParameter.Optional });
routes.MapRoute(
"Default,
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
But I have trouble in some routes, and I came across a new way to create routes in MVC 5.
The next example:
public class ClientController : BaseController
{
[HttpGet]
[Route"({controller}/{id})"]
public ActionResult Index(string id = null)
{
}
[Route"({controller}/{action}/{id})"]
public ActionResult GetAllClients(string id = null)
{
}
}
I wonder if it works well , and what is the real difference between them. Someone can help me?
Your first example is the configuration-based routing system, where you are handed a route builder and add your routes to it. This centralizes your route configuration code.
The second example is known as attribute routing. It allows you to specify the routes by applying attributes to controllers and action method.
They both still function. It comes down to a choice as to how you'd like to organize your code. And that's opinion based, so I will not delve into that discussion. Test both of them, and pick the one that you like best.
Note, these are not the only two options for routing. For example, SharpRouting adds functions to each controller to be called that create the routes through a fluent API. There are probably other options out there, or you can create your own!
For more information about routing in ASP.NET, see Microsoft's documentation.
Full disclaimer I work with the developer that created SharpRouting and we use it in our software (it may have been originally developed for our application, I'm not sure).

Areas in asp.net mvc 6.0 does not find Index file

I want to use Areas in an MVC 6.0 project.
These are my routes:
app.UseMvc(routes =>
{
// NOT work
routes.MapRoute("new_default",
"{area}/{controller=Home}/{action=Index}/{id?}");
// NOT work
routes.MapRoute("areaRoute", "{area:exists}/{controller}/{action}");
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
// Uncomment the following line to add a route for porting Web API 2 controllers.
// routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}");
});
I created on my root project an
"Areas" folder
"Application" folder
with a
Controllers/HomeController.cs
Views/Home/Index.cshtml
[Area("Application")]
[Route("[controller]")]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
When I go to the url:
domain/Application/Home it does not find the Index file I get a 404, Why?
Change your attribute route's template to like [Route("[area]/[controller]")]. Now your requests like /application/home should work fine.
Here area, controller and action are route tokens which would be replaced by the area, controller and action names that this attribute is decorated on. This is a new concept in ASP.NET 5 to reduce redundancy in supplying the same values again and again.
Note that when you decorate controllers/actions with attribute routes, they cannot be reached from conventional routes defined in your startup class.

Why does my route get redirected, this doesn't make any sense to me

I have these 2 routes mapped out:
routes.MapRoute(
"Admin",
"admin/{controller}/{action}/{id}",
new { controller = "Admin", action = "index", id = "" }
);
and then I have:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
So the 2 routes are identical, except the first one has /admin prefixed in the URLS.
This is what is happening, I have no idea how to explain this:
When I go to:
www.example.com/user/verify
it redirects to
www.example.com/admin/user/complete
instead of
www.example.com/user/complete
The action Verify simply redirects to Complete like this:
return RedirectToAction("complete", "user");
And all the complete action does is populate the ViewModel, and then calls the view.
How can it be redirecting and adding the prefix /admin/ to the URL?
I believe it is redirecting to the Admin route because the Admin route is the first with all the matching parameters (controller and action in the case provided). If you want to use something like this you will need to either look into using areas (MVC2) or using a named route redirect.
admin is your controller, you dont need an admin/controller/action the default route works just fine
all you need is an admin controller and the default route will find it for you
ie {controller}/{action}/{id}
will send /admin/addproduct to a controller named admin and an action called addproduct
you only need to add routes if you want something custom for example
/products/televisions/hdtv/2
where products would be a controller and the last 3 are category,subcategory and pagenumber
on the controller you point it to within your route.
hope that makes sense
Not sure exactly how your controllers are structured, but you can add a constraint to the first MapRoute to limit it to the specific controllers you want the route to apply to:
routes.MapRoute(
"Admin",
"admin/{controller}/{action}/{id}",
new { controller = "Admin", action = "index", id = "" } ,
new { controller = "[Some regex Expression - e.g. Admin]" }
);
Which will make the route only applicable for those controllers related routes. You can also use this tool to debug your routes. Depends how you have things structured, but like #NickLarson said - sounds like your using area functionality of MVC 2.
mvc goes from top to bottom while matching router, that' why you are dealing with this problem

Categories