ASP.NET Core MVC 概觀Overview of ASP.NET Core MVC

作者:Steve SmithBy Steve Smith

ASP.NET Core MVC 是建置使用模型檢視控制器設計模式之 Web 應用程式和 API 的豐富架構。ASP.NET Core MVC is a rich framework for building web apps and APIs using the Model-View-Controller design pattern.

什麼是 MVC 模式?What is the MVC pattern?

模型檢視控制器 (MVC) 架構模式可將一個應用程式劃分成三組主要元件:模型、檢視和控制器。The Model-View-Controller (MVC) architectural pattern separates an application into three main groups of components: Models, Views, and Controllers. 此模式有助於 Separation of Concerns (關注點分離)。This pattern helps to achieve separation of concerns. 透過此模式,使用者要求會路由傳送至控制器,再由其負責使用模型來執行使用者動作及 (或) 擷取查詢結果。Using this pattern, user requests are routed to a Controller which is responsible for working with the Model to perform user actions and/or retrieve results of queries. 控制器會選擇要向使用者顯示的檢視,並在其中提供任何所需的模型資料。The Controller chooses the View to display to the user, and provides it with any Model data it requires.

下圖顯示三個主要元件及彼此的參考關係:The following diagram shows the three main components and which ones reference the others:

MVC 模式

此職責劃分有助於您根據複雜度來調整應用程式,因為如果模型、檢視或控制器只有一項作業,就會更容易撰寫程式碼、進行偵錯及測試。This delineation of responsibilities helps you scale the application in terms of complexity because it's easier to code, debug, and test something (model, view, or controller) that has a single job. 如果程式碼相依於這三個區域當中兩個以上,就很難進行更新、測試及偵錯。It's more difficult to update, test, and debug code that has dependencies spread across two or more of these three areas. 例如,使用者介面邏輯通常比商務邏輯更常變更。For example, user interface logic tends to change more frequently than business logic. 如果將展示程式碼和商務邏輯結合成一個物件,則每次使用者介面變更時,都必須修改含有商務邏輯的物件。If presentation code and business logic are combined in a single object, an object containing business logic must be modified every time the user interface is changed. 這通常會導致錯誤,而需要在每次使用者介面微幅變更之後重新測試商務邏輯。This often introduces errors and requires the retesting of business logic after every minimal user interface change.

注意

檢視和控制器都相依於模型。Both the view and the controller depend on the model. 不過,模型並不相依於檢視或控制器。However, the model depends on neither the view nor the controller. 這是分離的主要優點之一。This is one of the key benefits of the separation. 此分離可讓模型在建立與測試時獨立於視覺展示。This separation allows the model to be built and tested independent of the visual presentation.

模型職責Model Responsibilities

MVC 應用程式中的模型代表應用程式的狀態,以及應用程式應該執行的任何商務邏輯或作業。The Model in an MVC application represents the state of the application and any business logic or operations that should be performed by it. 商務邏輯應該與保存應用程式狀態的任何實作邏輯,一起封裝在模型中。Business logic should be encapsulated in the model, along with any implementation logic for persisting the state of the application. 強型別檢視通常會使用 ViewModel 類型,其設計目的是為了包含要在該檢視上顯示的資料。Strongly-typed views typically use ViewModel types designed to contain the data to display on that view. 控制器會從模型建立並填入這些 ViewModel 執行個體。The controller creates and populates these ViewModel instances from the model.

檢視職責View Responsibilities

檢視會負責透過使用者介面展示內容。Views are responsible for presenting content through the user interface. 他們使用 Razor view engine將 .net 程式碼內嵌在 HTML 標籤中。They use the Razor view engine to embed .NET code in HTML markup. 檢視內應該有基本邏輯,而且其中的任何邏輯都應該與展示內容相關。There should be minimal logic within views, and any logic in them should relate to presenting content. 如果您需要在檢視檔案中執行大量邏輯以便顯示複雜模型中的資料,請考慮使用檢視元件、ViewModel 或檢視範本來簡化檢視。If you find the need to perform a great deal of logic in view files in order to display data from a complex model, consider using a View Component, ViewModel, or view template to simplify the view.

控制器職責Controller Responsibilities

控制器是處理使用者互動、使用模型,並在最終選取要呈現之檢視的元件。Controllers are the components that handle user interaction, work with the model, and ultimately select a view to render. 在 MVC 應用程式中,檢視只會顯示資訊,而控制器則會處理及回應使用者輸入和互動。In an MVC application, the view only displays information; the controller handles and responds to user input and interaction. 在 MVC 模式中,控制器是初始進入點,負責選取要使用的模型類型及要呈現的檢視 (如其名稱所指,它會控制應用程式回應指定要求的方式)。In the MVC pattern, the controller is the initial entry point, and is responsible for selecting which model types to work with and which view to render (hence its name - it controls how the app responds to a given request).

注意

控制器不應該因太多職責而過於複雜。Controllers shouldn't be overly complicated by too many responsibilities. 若要防止控制器邏輯變得過於複雜,請將控制器中的商務邏輯推送到領域模型中。To keep controller logic from becoming overly complex, push business logic out of the controller and into the domain model.

提示

如果您發現控制器動作經常執行相同的動作類型,請這些常見的動作移到篩選中。If you find that your controller actions frequently perform the same kinds of actions, move these common actions into filters.

什麼是 ASP.NET Core MVCWhat is ASP.NET Core MVC

ASP.NET Core MVC 架構是輕量型、開放原始碼且可高度測試的展示架構,並已經過最佳化可搭配 ASP.NET Core 使用。The ASP.NET Core MVC framework is a lightweight, open source, highly testable presentation framework optimized for use with ASP.NET Core.

ASP.NET Core MVC 可讓您透過模式建立動態網站,以清楚關注點分離。ASP.NET Core MVC provides a patterns-based way to build dynamic websites that enables a clean separation of concerns. 它可讓您完全掌控標記,支援適合 TDD 的開發,並使用最新的網站標準。It gives you full control over markup, supports TDD-friendly development and uses the latest web standards.

功能Features

ASP.NET Core MVC 包括下列各項:ASP.NET Core MVC includes the following:

路由Routing

ASP.NET Core MVC 是以 ASP.NET Core 路由為建置基礎且功能強大的 URL 對應元件,可讓您建置具有可理解且可搜尋之 URL 的應用程式。ASP.NET Core MVC is built on top of ASP.NET Core's routing, a powerful URL-mapping component that lets you build applications that have comprehensible and searchable URLs. 這可讓您定義適用於搜尋引擎最佳化 (SEO) 和連結產生的應用程式 URL 命名模式,而不需要考慮如何在網頁伺服器上組織檔案。This enables you to define your application's URL naming patterns that work well for search engine optimization (SEO) and for link generation, without regard for how the files on your web server are organized. 您可以使用方便且支援路由值條件約束、預設值和選用值的路由範本語法,來定義您的路由。You can define your routes using a convenient route template syntax that supports route value constraints, defaults and optional values.

「以慣例為基礎的路由」可讓您全域定義應用程式接受的的 URL 格式,以及每種格式如何對應至指定控制器上的特定動作方法。Convention-based routing enables you to globally define the URL formats that your application accepts and how each of those formats maps to a specific action method on given controller. 當收到內送要求時,路由引擎會剖析 URL 定並將它對應至其中一個已定義的 URL 格式,再呼叫關聯控制器的動作方法。When an incoming request is received, the routing engine parses the URL and matches it to one of the defined URL formats, and then calls the associated controller's action method.

routes.MapRoute(name: "Default", template: "{controller=Home}/{action=Index}/{id?}");

「屬性路由」可讓您指定路由資訊,方法是使用定義應用程式路由的屬性來裝飾控制器和動作。Attribute routing enables you to specify routing information by decorating your controllers and actions with attributes that define your application's routes. 這表示路由定義會緊接著其所關聯的控制器和動作。This means that your route definitions are placed next to the controller and action with which they're associated.

[Route("api/[controller]")]
public class ProductsController : Controller
{
    [HttpGet("{id}")]
    public IActionResult GetProduct(int id)
    {
      ...
    }
}

模型繫結Model binding

ASP.NET Core MVC 模型繫結會將用戶端要求資料 (表單值、路由資料、查詢字串參數、HTTP 標頭),轉換成控制器可以處理的物件。ASP.NET Core MVC model binding converts client request data (form values, route data, query string parameters, HTTP headers) into objects that the controller can handle. 因此,您的控制器邏輯不必理解內送要求資料,它只會將資料當作其動作方法的參數。As a result, your controller logic doesn't have to do the work of figuring out the incoming request data; it simply has the data as parameters to its action methods.

public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null) { ... }

模型驗證Model validation

ASP.NET Core MVC 支援使用資料註解驗證屬性來裝置模型物件,藉此進行驗證ASP.NET Core MVC supports validation by decorating your model object with data annotation validation attributes. 這些驗證屬性會在用戶端進行檢查,再將其值張貼至伺服器,而且會在伺服器上進行檢查,再呼叫控制器動作。The validation attributes are checked on the client side before values are posted to the server, as well as on the server before the controller action is called.

using System.ComponentModel.DataAnnotations;
public class LoginViewModel
{
    [Required]
    [EmailAddress]
    public string Email { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }

    [Display(Name = "Remember me?")]
    public bool RememberMe { get; set; }
}

控制器動作:A controller action:

public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
    if (ModelState.IsValid)
    {
      // work with the model
    }
    // At this point, something failed, redisplay form
    return View(model);
}

此架構會在用戶端和伺服器上處理驗證要求資料。The framework handles validating request data both on the client and on the server. 模型類型上所指定的驗證邏輯會以不顯眼的註解形式新增呈現的檢視,並使用 jQuery 驗證在瀏覽器中強制執行。Validation logic specified on model types is added to the rendered views as unobtrusive annotations and is enforced in the browser with jQuery Validation.

相依性插入Dependency injection

ASP.NET Core 內建相依性插入 (DI) 支援。ASP.NET Core has built-in support for dependency injection (DI). 在 ASP.NET Core MVC 中,控制器可以透過其建構函式要求所需服務,以便遵循 Explicit Dependencies Principle (明確的相依性原則)。In ASP.NET Core MVC, controllers can request needed services through their constructors, allowing them to follow the Explicit Dependencies Principle.

您的應用程式也可以使用 @inject 指示詞,在檢視檔案中使用相依性插入Your app can also use dependency injection in view files, using the @inject directive:

@inject SomeService ServiceName

<!DOCTYPE html>
<html lang="en">
<head>
    <title>@ServiceName.GetTitle</title>
</head>
<body>
    <h1>@ServiceName.GetTitle</h1>
</body>
</html>

篩選器Filters

篩選可協助開發人員封裝交叉關注,例如例外狀況處理或授權。Filters help developers encapsulate cross-cutting concerns, like exception handling or authorization. 篩選可執行動作方法的自訂處理前後邏輯,並可設定為在指定要求之執行管線內的特定時間點執行。Filters enable running custom pre- and post-processing logic for action methods, and can be configured to run at certain points within the execution pipeline for a given request. 篩選可當作屬性套用至控制器或動作 (也可全域執行)。Filters can be applied to controllers or actions as attributes (or can be run globally). 此架構隨附數個篩選 (例如Authorize)。Several filters (such as Authorize) are included in the framework. [Authorize] 是用來建立 MVC 授權篩選的屬性。[Authorize] is the attribute that is used to create MVC authorization filters.

[Authorize]
public class AccountController : Controller

Areas

區域 提供將大型 ASP.NET Core MVC Web 應用程式分割成較小功能群組的方式。Areas provide a way to partition a large ASP.NET Core MVC Web app into smaller functional groupings. 一個區域是應用程式內的一個 MVC 結構。An area is an MVC structure inside an application. 在 MVC 專案中,模型、控制器和檢視等邏輯元件會保留在不同的資料夾中,而且 MVC 會使用命名慣例來建立這些元件之間的關聯性。In an MVC project, logical components like Model, Controller, and View are kept in different folders, and MVC uses naming conventions to create the relationship between these components. 針對大型應用程式,將應用程式分割成個別高功能層級區域可能較有利。For a large app, it may be advantageous to partition the app into separate high level areas of functionality. 例如,電子商務應用程式具有多個業務單位,例如結帳、帳單和搜尋等等。上述每個單位都有自己的邏輯元件視圖、控制器和模型。For instance, an e-commerce app with multiple business units, such as checkout, billing, and search etc. Each of these units have their own logical component views, controllers, and models.

Web APIWeb APIs

ASP.NET Core MVC 除了是建立網站的理想平台之外,也對建置 Web API 提供絕佳的支援。In addition to being a great platform for building web sites, ASP.NET Core MVC has great support for building Web APIs. 您可以建置可供廣大用戶端使用的服務,包括瀏覽器和行動裝置。You can build services that reach a broad range of clients including browsers and mobile devices.

此架構包含使用內建支援的 HTTP 內容交涉支援,以格式化資料為 JSON 或 XML。The framework includes support for HTTP content-negotiation with built-in support to format data as JSON or XML. 撰寫自訂格式器可新增您專屬格式的支援。Write custom formatters to add support for your own formats.

使用連結產生可支援超媒體。Use link generation to enable support for hypermedia. 輕鬆就可支援跨原始來源資源共用 (CORS) ,讓您的 Web API 可跨多個 Web 應用程式共用。Easily enable support for cross-origin resource sharing (CORS) so that your Web APIs can be shared across multiple Web applications.

可測試性Testability

此架構使用介面和相依性插入,因此相當適用於單元測試,而此架構所包含的功能 (例如 Entity Framework 的 TestHost 和 InMemory 提供者) 也讓您可以輕鬆快速地進行整合測試The framework's use of interfaces and dependency injection make it well-suited to unit testing, and the framework includes features (like a TestHost and InMemory provider for Entity Framework) that make integration tests quick and easy as well. 深入了解如何測試控制器邏輯Learn more about how to test controller logic.

Razor 查看引擎Razor view engine

ASP.NET CORE MVC 視圖器會使用 Razor view engine來呈現視圖。ASP.NET Core MVC views use the Razor view engine to render views. Razor 是一種精簡、易懂且流暢的範本標記語言,可使用內嵌 c # 程式碼來定義視圖。Razor is a compact, expressive and fluid template markup language for defining views using embedded C# code. Razor 用來在伺服器上動態產生 web 內容。Razor is used to dynamically generate web content on the server. 您可以完全混合伺服端程式碼以及用戶端內容和程式碼。You can cleanly mix server code with client side content and code.

<ul>
    @for (int i = 0; i < 5; i++) {
        <li>List item @i</li>
    }
</ul>

Razor您可以使用 view engine 來定義版面配置、部分視圖和可取代的區段。Using the Razor view engine you can define layouts, partial views and replaceable sections.

強型別檢視Strongly typed views

Razor MVC 中的 views 可以根據您的模型以強型別為基礎。Razor views in MVC can be strongly typed based on your model. 控制器可以將強型別模型傳遞至檢視,讓您的檢視具有類型檢查和 IntelliSense 支援。Controllers can pass a strongly typed model to views enabling your views to have type checking and IntelliSense support.

例如,下列檢視會呈現 IEnumerable<Product> 類型的模型:For example, the following view renders a model of type IEnumerable<Product>:

@model IEnumerable<Product>
<ul>
    @foreach (Product p in Model)
    {
        <li>@p.Name</li>
    }
</ul>

標籤協助程式Tag Helpers

標記 協助程式可讓伺服器端程式碼參與建立和轉譯檔案中的 HTML 元素 Razor 。Tag Helpers enable server side code to participate in creating and rendering HTML elements in Razor files. 您可以使用標籤協助程式定義自訂標籤 (例如 <environment>),或修改現有標籤 (例如 <label>) 的行為。You can use tag helpers to define custom tags (for example, <environment>) or to modify the behavior of existing tags (for example, <label>). 標籤協助程式會根據元素名稱及其屬性,繫結至特定元素。Tag Helpers bind to specific elements based on the element name and its attributes. 其提供伺服器端轉譯優點,同時仍然保留 HTML 編輯體驗。They provide the benefits of server-side rendering while still preserving an HTML editing experience.

有許多適用於一般工作 (例如建立表單和連結、載入資產等) 的內建標籤協助程式,還有更多位於公用 GitHub 存放庫及作為 NuGet 套件來提供。There are many built-in Tag Helpers for common tasks - such as creating forms, links, loading assets and more - and even more available in public GitHub repositories and as NuGet packages. 標籤協助程式是以 C# 編寫,並根據項目名稱、屬性名稱或上層標籤來設定目標 HTML 項目。Tag Helpers are authored in C#, and they target HTML elements based on element name, attribute name, or parent tag. 例如,內建 LinkTagHelper 可用來建立 AccountsControllerLogin 動作的連結:For example, the built-in LinkTagHelper can be used to create a link to the Login action of the AccountsController:

<p>
    Thank you for confirming your email.
    Please <a asp-controller="Account" asp-action="Login">Click here to Log in</a>.
</p>

EnvironmentTagHelper 可根據執行階段環境 (例如開發、預備或生產),將不同的指令碼加入檢視:The EnvironmentTagHelper can be used to include different scripts in your views (for example, raw or minified) based on the runtime environment, such as Development, Staging, or Production:

<environment names="Development">
    <script src="~/lib/jquery/dist/jquery.js"></script>
</environment>
<environment names="Staging,Production">
    <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"
            asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
            asp-fallback-test="window.jQuery">
    </script>
</environment>

標籤協助程式提供方便 HTML 的開發體驗,以及豐富的 IntelliSense 環境,可用於建立 HTML 和 Razor 標記。Tag Helpers provide an HTML-friendly development experience and a rich IntelliSense environment for creating HTML and Razor markup. 大部分的內建標籤協助程式都是以現有的 HTML 元素為目標,並提供元素的伺服器端屬性。Most of the built-in Tag Helpers target existing HTML elements and provide server-side attributes for the element.

檢視元件View Components

檢視元件可讓您封裝轉譯邏輯,並在整個應用程式中重複使用。View Components allow you to package rendering logic and reuse it throughout the application. 其類似於部分檢視,但具有相關聯的邏輯。They're similar to partial views, but with associated logic.

相容性版本Compatibility version

SetCompatibilityVersion 方法可讓應用程式加入或退出 ASP.NET Core MVC 2.1 或更新版本所引入的可能重大行為變更。The SetCompatibilityVersion method allows an app to opt-in or opt-out of potentially breaking behavior changes introduced in ASP.NET Core MVC 2.1 or later.

如需詳細資訊,請參閱ASP.NET Core MVC 的相容性版本For more information, see ASP.NET Core MVC 的相容性版本.

其他資源Additional resources