How to specify the view location in asp.net core mvc when using custom locations?

前端 未结 8 2172
死守一世寂寞
死守一世寂寞 2020-11-30 22:59

Let\'s say I have a controller that uses attribute based routing to handle a requested url of /admin/product like so:



        
8条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-30 23:33

    Though anwers above may be correct, I'd like to add something that is a little bit more "basic":

    -There is (a lot of) implicit routing behaviour in MVC .NET

    -You can make everything explicit also

    So, how does that work for .NET MVC?

    Default

    -The default "route" is protocol://server:port/ , e.g. http://localhost:607888/ If you dont have any controller with a explicit route, and dont define any startup defaults, that wont work. This will:

    app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Special}/{action=Index}");
            });
    

    Controller Routes

    And if you add a class SpecialController : Controller with a Index() method, your http://localhost:.../ will and up there. Note: NameController => post fix Controller is left out, implicit naming convention

    If you rather define your routes explicit on the controllers, use this:

    [Route("Special")]//explicit route
    public class SpecialController : Controller
    { ....
    
    => http://localhost:/Special will end up on this controller
    

    For mapping http requests to controller methods, you can also add explicit [Route(...)] information to your Methods:

    // GET: explicit route page
    [HttpGet("MySpecialIndex")]
    public ActionResult Index(){...}
    
    => http://localhost:/Special/MySpecialIndex will end up on SpecialController.Index()
    

    View routes

    Now suppose your Views folder is like this:

    Views\
       Special1\
              Index1.cshtml
       Special\
              Index.cshtml
    

    How does the Controller "finds" its way to the views? The example here is

    [Route("Special")]//explicit route
    public class Special1Controller : Controller
    {
        // GET: Default route page
        [HttpGet]
        public ActionResult Index()
        {
            //
            // Implicit path, implicit view name: Special1 -> View  = Views/Special/Index.cshtml
            //
            //return View();
    
            //
            // Implicit path, explicit view name, implicit extention 
            // Special  -> View  = Views/Special/Index.cshtml
            //
             //return View("Index");
    
            //
            // Everything explcit
            //
            return View("Views/Special1/Index1.cshtml");
        }
    

    So, we have:

    return View(); => everything implicit, take Method name as view, controller path as view path etc. http://<>:<>/Special => Method = Index(), View = /Views/Special/Index.cshtml

    return View("Index"); //Explicit view name, implicit paths and extention => Method = Special1Controller.Index(), View = /Views/Special/Index.cshtml

    return View("Views/Special1/Index1.cshtml"); // method implicit, view explicit => http://<>:<>/Special, Method = Special1Controller.Index(), View = /Views/Special1/Index1.cshtml

    And if you combine explicit mapping to methods and views: => http://<>:<>/Special/MySpecialIndex, Method = Special1Controller.Index(), View = /Views/Special1/Index1.cshtml

    Then finally, why would you make everything implicit? The pros are less administration that is error prone, and you force some clean administration in your naming and setup of folders The con is a lot of magic is going on, that everybody needs to understand.

    Then why would you make everything explicit? Pros: This is more readable for "everyone". No need to know all implicit rules. And more flexibility for changing routes and maps explcitly. The chance on conflicts between controllers and route paths is also a little less.

    Finally: of course you can mix explicit and implicit routing.

    My preference would be everything explicit. Why? I like explicit mappings and separation of concerns. class names and method names can have a naming convention, without interference with your request naming conventions. E.g. suppose my classes/methods are camelCase, my queries lowercase, then that would work nicely: http://..:../whatever/something and ControllerX.someThing (Keep in mind, Windows is kindof case insensitive, Linux by know means is! And modern .netcore Docker components may end up on a Linux platform!) I also dont like "big monolitic" classes with X000 lines of code. Splitting your controllers but not your queries works perfectly, by giving them explicit the same http query routes. Bottom line: know how it works, and choose a strategy whisely!

提交回复
热议问题