受欢迎的博客标签

custom extend View in ASP.NET Core 3.0

Published

In this blog, I am going to provide a walk-through on developing a web application using ASP.NET Core 3.0, connecting it to a database (database-first) using the Entity Framework Core 3.0 command, and performing CRUD operations using scaffolding (code generator). I am going to develop a sample application for inventory management with basic operations.

This blog post will discuss the following:

 

Creating a New View Engine in ASP.NET Core

How to access views from a custom folder in ASP.NET Core

How to change wwwroot folder name in ASP.NET Core

One of the things I like most when developing ASP.NET application using the MVC model (if you don’t know yet what it is, read here) is the emphasis put to the project’s folder structure: the separation between the three logical aspects is reflected to the directory tree, expecially – since the Model is often injected from external libraries and their abstraction layers – the /Controllers/ and /Views/ folders, hosting respectively the input handlers and the user interface of our application.

Among these, the /Views/ folder plays a peculiar role in relation with the filesystem because it is looked by the View Engine to retrieve the View .cshtml and/or .aspx files implicitly or expicitly referenced by each Controller. The search is handled using a set of predefined patterns that come by the name of default location scheme. Here’s a portion of it, used by the Razor View Engine to lookup the standard Views:

ViewLocationFormats = new string[]
{
    "~/Views/{1}/{0}.cshtml",
    "~/Views/Shared/{0}.cshtml",
    "~/Pages/Shared/{0}.vbhtml"
};

by default the ASP.NET MVC engine searches the following folders for View pages:

/Views/{Controller_Name}/{Action}.cshtml
/Views/Shared/{Action}.cshtml

However I want to put some of my View pages like this:

/Views/{Namespace}/{Controller_Name}/{Action}.cshtml

 

Back to our example, we can notice two placeholders, {0} and {1}, referring to the Action and its Controller. What happens under the hood is the View Engine checking for the presence of a suitable View file in these folder paths, starting with the most specific ones and then looking in the directory hosting the shared views.

Question is: can we add other paths? Or, to be more specific: can we edit these lists, maybe adding one of more folders to reflect the folder structure we used to organize our Views, or are we forced to use the default locations to avoid errors like the following one?

 

You can return view placed in custom sub-folders, from controller action by, giving out full view path in return statement,ex:

public ActionResult Create()
{
    return View("~/Views/ProEnhance/Employee/Create.cshtml");
}

here,

ProEnhance - user defined folder

Employee - Controller Name

Create - action Name


 
In Startup.cs file

 

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
         ...

         services.Configure<RazorViewEngineOptions>(o =>
         {
             // {2} is area, {1} is controller,{0} is the action    
             o.ViewLocationFormats.Clear(); 
             o.ViewLocationFormats.Add("/Controllers/{1}/Views/{0}" + RazorViewEngine.ViewExtension);
             o.ViewLocationFormats.Add("/Controllers/Shared/Views/{0}" + RazorViewEngine.ViewExtension);

             // Untested. You could remove this if you don't care about areas.
             o.AreaViewLocationFormats.Clear();
             o.AreaViewLocationFormats.Add("/Areas/{2}/Controllers/{1}/Views/{0}" + RazorViewEngine.ViewExtension);
             o.AreaViewLocationFormats.Add("/Areas/{2}/Controllers/Shared/Views/{0}" + RazorViewEngine.ViewExtension);
             o.AreaViewLocationFormats.Add("/Areas/Shared/Views/{0}" + RazorViewEngine.ViewExtension);
        });

        ...         
    }

...
}

 

How to change wwwroot folder name in ASP.NET Core

In Startup.cs file

Go to ConfigureServices method.

services.AddMvc(); // Replace this with following

services
           .AddMvc()
           .SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Latest)
           .AddMvcOptions(options =>
           {
               options.EnableEndpointRouting = false;
                 // Add MVC services to the services container.
                 //因为mvc 不能正确的传MongodbID值给viewmodel,修改记录时会新增加一条记录,所以新加一个模型绑定类,同时在相应的*.cshtml 加上@Html.HiddenFor(model => model._id)语句
                 //原因及其解决办法:see:http://www.joe-stevens.com/2011/06/12/model-binding-mongodb-objectid-with-asp-net-mvc/
                 //模型绑定
                 //http://stackoverflow.com/questions/27448198/what-is-the-correct-way-to-create-custom-model-binders-in-mvc6?rq=1
               options.ModelBinderProviders.Insert(0, new ObjectIdModelBinderProvider());

                 //Mvc级别全局错误处理 http://stackoverflow.com/questions/28385889/global-exception-handling-in-asp-net-5
                 //https://github.com/aspnet/Logging/tree/dev/src
                 // options.Filters.Add(new CustomExceptionHandFilterAttribute());
             });