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();
}
Related
Im trying to manage my routing settings for my projet but I don't understand everything, I want to make some actions or controllers names optional in the url.
For example I have a controller "HomeController" with a "SignIn()" action, I want it to be reachable with the url "/signin" and not "/home/signin".
Same for a controller named "ProjectsController" with an action "Details(int id)", I want it to be reachable with "/projects/348" and not "/projects/details/348".
I didn't modify the default endpoint configuration:
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
How can I make some controllers name and actions name optional ? And after that will I be able to still use tag helpers for links with asp-controller and asp-action ?
I think you have to use route attributes. For example for your SignIn action
public partial class HomeController : Controller
{
[Route("~/signin")]
public IActionResult SignIn()
{
.....
}
}
and use the same template for another special actions
and you can have several routes for one action too
[Route("~/signin")]
[Route("~/home/signin")]
public IActionResult SignIn()
{
.....
}
On latest ASP.NET MVC CORE 2 default template, i am trying to change default action by modifying controller and action as below. I am expecting to see login page as default but i am having 404 http error. What I am doing wrong ?
You can verify this issue on default ASP.NET CORE 2 MVC project.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Account}/{action=Login}/{id?}");
});
}
If you look at the AccountController class, you'll see it's decorated with a Route attribute, like so:
[Route("[controller]/[action]")]
public class AccountController : Controller
However, if you look at the HomeController class, you'll see that it is not decorated with such an attribute:
public class HomeController : Controller
Because the AccountController is using Attribute routing, it will not be picked up using the Conventional routing template. The docs explain this mutual exclusivity:
Actions that define attribute routes cannot be reached through the conventional routes and vice-versa.
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
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?}");
});
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.