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()
{
.....
}
Related
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();
}
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 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.
I just checked attribute routing in ASP.NET Web API 2. In that I can use RoutePrefix attribute at class level to set prefix to all action name URL. Mostly I use action name as URL routing for particular action. Is there any way that I write a single line of code which set action name as default value for Route attribute for all action? I want that because I am using action name as URI template, so it will be duplication on top of each action name.
[RoutePrefix("api")]
//[Route("{action}")] // Possible I could write like this
public class BooksController : ApiController
{
[Route("GetBooks")] //Route value same as action name, http://localhost:xxxx/api/GetBooks
public object GetBooks() { ... }
[Route("CreateBook")] //Route value same as action name, http://localhost:xxxx/api/CreateBook
[HttpPost]
public object CreateBook(Book book) { ... }
}
EDIT 1: I want to use attribute routing because I want web API URL pattern like this http://hostname/api/action_name. My application uses single API controller, so I don't want controller name as part of action URI.
Solution: [Route("{action}")] on class level will work, if you remove route attribute from all other action unless you want to override for any action.
Personally I would just not use attribute routing and instead use the standard route mapping. So in your App_Start/RouteConfig.cs file:
routes.MapRoute(
name: "Api",
url: "api/{action}",
defaults: new { controller = "Books" }
);