將控制器新增至 ASP.NET Core MVC 應用程式Add a controller to an ASP.NET Core MVC app

作者:Rick AndersonBy Rick Anderson

Model-View-Controller (MVC) 架構模式可將一個應用程式劃分成三個主要元件:模型 (M)、檢視 (V) 和控制器 (C)。The Model-View-Controller (MVC) architectural pattern separates an app into three main components: Model, View, and Controller. MVC 模式可協助您建立比傳統整合型應用程式更可測試且更易於更新的應用程式。The MVC pattern helps you create apps that are more testable and easier to update than traditional monolithic apps. MVC 架構的應用程式包含:MVC-based apps contain:

  • 模型 (M):代表應用程式資料的類別。Models: Classes that represent the data of the app. 模型類別使用驗證邏輯對該資料強制執行商務規則。The model classes use validation logic to enforce business rules for that data. 通常,模型物件會在資料庫中擷取並儲存模型狀態。Typically, model objects retrieve and store model state in a database. 在本教學課程中,Movie 模型會從資料庫擷取電影資料,將其提供給檢視或更新它。In this tutorial, a Movie model retrieves movie data from a database, provides it to the view or updates it. 更新的資料會寫入資料庫。Updated data is written to a database.

  • 檢視 (V):檢視是顯示應用程式使用者介面 (UI) 的元件。Views: Views are the components that display the app's user interface (UI). 一般而言,此 UI 會顯示模型資料。Generally, this UI displays the model data.

  • 控制器 (C):處理瀏覽器要求的類別。Controllers: Classes that handle browser requests. 它們會擷取模型資料,並呼叫傳回回應的檢視範本。They retrieve model data and call view templates that return a response. 在 MVC 應用程式中,檢視只能顯示資訊;控制器則會處理和回應使用者輸入和互動。In an MVC app, the view only displays information; the controller handles and responds to user input and interaction. 例如,控制器會處理路由資料和查詢字串值,並將這些值傳遞至模型。For example, the controller handles route data and query-string values, and passes these values to the model. 此模型可能會使用這些值來查詢資料庫。The model might use these values to query the database. 例如,https://localhost:1234/Home/About 具有 Home (控制器) 和 About (在首頁控制器上呼叫的動作方法) 的路由資料。For example, https://localhost:1234/Home/About has route data of Home (the controller) and About (the action method to call on the home controller). https://localhost:1234/Movies/Edit/5 是要使用電影控制器編輯識別碼 = 5 之電影的要求。https://localhost:1234/Movies/Edit/5 is a request to edit the movie with ID=5 using the movie controller. 本教學課程稍後會說明路由資料。Route data is explained later in the tutorial.

MVC 模式可協助您建立應用程式,用來隔離應用程的不同層面 (輸入邏輯、商務邏輯和 UI 邏輯),同時提供這些項目之間的鬆散結合。The MVC pattern helps you create apps that separate the different aspects of the app (input logic, business logic, and UI logic), while providing a loose coupling between these elements. 此模式指定每一種邏輯應該位於應用程式中的位置。The pattern specifies where each kind of logic should be located in the app. UI 邏輯位於檢視。The UI logic belongs in the view. 輸入邏輯位於控制器。Input logic belongs in the controller. 商務邏輯則位於模型。Business logic belongs in the model. 這項隔離可協助您管理建置應用程式時的複雜度,因為它可讓您一次處理實作的其中一個層面,而不影響另一個層面的程式碼。This separation helps you manage complexity when you build an app, because it enables you to work on one aspect of the implementation at a time without impacting the code of another. 例如,您可以處理檢視程式碼,而不需要根據商務邏輯程式碼。For example, you can work on the view code without depending on the business logic code.

本教學課程系列中涵蓋了這些概念,並且顯示如何使用它們來建置電影應用程式。We cover these concepts in this tutorial series and show you how to use them to build a movie app. MVC 專案包含「控制器」 和「檢視」 的資料夾。The MVC project contains folders for the Controllers and Views.

新增控制器Add a controller

  • 在 [方案總管] 中,以滑鼠右鍵按一下 [控制器] > [新增] > [控制器]
    操作功能表
    In Solution Explorer, right-click Controllers > Add > Controller Contextual menu

  • 在 [新增 Scaffold] 對話方塊中,選取 [MVC 控制器 - 空白] In the Add Scaffold dialog box, select MVC Controller - Empty

    新增 MVC 控制器並將其命名

  • 在 [Add Empty MVC Controller] (新增空白 MVC 控制器) 對話方塊中,輸入 HelloWorldController,然後選取 [新增] 。In the Add Empty MVC Controller dialog, enter HelloWorldController and select ADD.

以下列內容取代 Controllers/HelloWorldController.cs 的內容:Replace the contents of Controllers/HelloWorldController.cs with the following:

using Microsoft.AspNetCore.Mvc;
using System.Text.Encodings.Web;

namespace MvcMovie.Controllers
{
    public class HelloWorldController : Controller
    {
        // 
        // GET: /HelloWorld/

        public string Index()
        {
            return "This is my default action...";
        }

        // 
        // GET: /HelloWorld/Welcome/ 

        public string Welcome()
        {
            return "This is the Welcome action method...";
        }
    }
}

控制器中的每個 public 方法可呼叫作為 HTTP 端點。Every public method in a controller is callable as an HTTP endpoint. 在上述範例中,這兩種方法都會傳回一個字串。In the sample above, both methods return a string. 請注意每個方法之前的註解。Note the comments preceding each method.

HTTP 端點是 Web 應用程式中的可設定目標 URL,例如 https://localhost:5001/HelloWorld,其結合使用的通訊協定:HTTPS、網頁伺服器的網路位置 (包括 TCP 連接埠):localhost:5001,以及目標 URI HelloWorldAn HTTP endpoint is a targetable URL in the web application, such as https://localhost:5001/HelloWorld, and combines the protocol used: HTTPS, the network location of the web server (including the TCP port): localhost:5001 and the target URI HelloWorld.

第一個註解指出這是 HTTP GET 方法,叫用方法是將 /HelloWorld/ 附加至基底 URL。The first comment states this is an HTTP GET method that's invoked by appending /HelloWorld/ to the base URL. 第二個註解會指定 HTTP GET 方法,叫用方法是將 /HelloWorld/Welcome/ 附加至 URL。The second comment specifies an HTTP GET method that's invoked by appending /HelloWorld/Welcome/ to the URL. 稍後在本教學課程中,您將使用 Scaffolding 引擎產生 HTTP POST 方法來更新資料。Later on in the tutorial the scaffolding engine is used to generate HTTP POST methods which update data.

在非偵錯模式中執行應用程式,並將 "HelloWorld" 附加至網址列中的路徑。Run the app in non-debug mode and append "HelloWorld" to the path in the address bar. Index 方法會傳回一個字串。The Index method returns a string.

顯示應用程式回應 "This is my default action" 的瀏覽器視窗

MVC 會根據傳入 URL 叫用控制器類別 (和其中的動作方法)。MVC invokes controller classes (and the action methods within them) depending on the incoming URL. MVC 使用的預設 URL 路由邏輯使用像這樣的格式來判斷要叫用的程式碼:The default URL routing logic used by MVC uses a format like this to determine what code to invoke:

/[Controller]/[ActionName]/[Parameters]

您可以在 Startup.cs 檔案的 Configure 方法中設定路由格式。The routing format is set in the Configure method in Startup.cs file.

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

當您瀏覽至應用程式而不提供任何 URL 區段時,則會預設為上方醒目提示之範本行中指定的 "Home" 控制器和 "Index" 方法。When you browse to the app and don't supply any URL segments, it defaults to the "Home" controller and the "Index" method specified in the template line highlighted above.

第一個 URL 區段決定要執行的控制器類別。The first URL segment determines the controller class to run. 因此,localhost:xxxx/HelloWorld 會對應至 HelloWorldController 類別。So localhost:xxxx/HelloWorld maps to the HelloWorldController class. URL 區段的第二部分則決定類別上的動作方法。The second part of the URL segment determines the action method on the class. 因此,localhost:xxxx/HelloWorld/Index 會導致 HelloWorldController 類別的 Index 方法執行。So localhost:xxxx/HelloWorld/Index would cause the Index method of the HelloWorldController class to run. 請注意,您只需要瀏覽至 localhost:xxxx/HelloWorld,根據預設就會呼叫 Index 方法。Notice that you only had to browse to localhost:xxxx/HelloWorld and the Index method was called by default. 這是因為 Index 是未明確指定方法名稱時,在控制器上呼叫的預設方法。This is because Index is the default method that will be called on a controller if a method name isn't explicitly specified. URL 區段的第三個部分 (id) 是路由資料。The third part of the URL segment ( id) is for route data. 本教學課程稍後會說明路由資料。Route data is explained later in the tutorial.

瀏覽至 https://localhost:xxxx/HelloWorld/WelcomeBrowse to https://localhost:xxxx/HelloWorld/Welcome. Welcome 方法隨即執行,並傳回字串 This is the Welcome action method...The Welcome method runs and returns the string This is the Welcome action method.... 在此 URL 中,控制器是 HelloWorld,而 Welcome 是動作方法。For this URL, the controller is HelloWorld and Welcome is the action method. 您尚未使用 URL 的 [Parameters] 部分。You haven't used the [Parameters] part of the URL yet.

顯示應用程式回應 "This is the Welcome action method" 的瀏覽器視窗

修改程式碼 ,將 URL 中的某些參數資訊傳遞到控制器。Modify the code to pass some parameter information from the URL to the controller. 例如,/HelloWorld/Welcome?name=Rick&numtimes=4For example, /HelloWorld/Welcome?name=Rick&numtimes=4. 變更 Welcome 方法以包含兩個參數,如下列程式碼所示。Change the Welcome method to include two parameters as shown in the following code.

// GET: /HelloWorld/Welcome/ 
// Requires using System.Text.Encodings.Web;
public string Welcome(string name, int numTimes = 1)
{
    return HtmlEncoder.Default.Encode($"Hello {name}, NumTimes is: {numTimes}");
}

上述程式碼:The preceding code:

  • 使用 C# 選擇性參數功能來指出若未針對 numTimes 參數傳遞任何值時,該參數預設為 1。Uses the C# optional-parameter feature to indicate that the numTimes parameter defaults to 1 if no value is passed for that parameter.
  • 使用 HtmlEncoder.Default.Encode 來保護應用程式免於遭受惡意輸入 (也就是 JavaScript) 攻擊。Uses HtmlEncoder.Default.Encode to protect the app from malicious input (namely JavaScript).
  • $"Hello {name}, NumTimes is: {numTimes}" 中使用字串插值Uses Interpolated Strings in $"Hello {name}, NumTimes is: {numTimes}".

執行應用程式,然後瀏覽至:Run the app and browse to:

https://localhost:xxxx/HelloWorld/Welcome?name=Rick&numtimes=4

(將 xxxx 取代為您的連接埠編號)。您可以在 URL 中針對 namenumtimes 嘗試不同的值。(Replace xxxx with your port number.) You can try different values for name and numtimes in the URL. MVC 模型繫結系統會自動將網址列上查詢字串中的具名參數對應至方法中的參數。The MVC model binding system automatically maps the named parameters from the query string in the address bar to parameters in your method. 如需詳細資訊,請參閱模型繫結See Model Binding for more information.

瀏覽器視窗,其中顯示應用程式回應 Hello Rick, NumTimes is:4

在上方的影像中,不會使用 URL 區段 (Parameters) ,namenumTimes 則以查詢字串的方式傳遞。In the image above, the URL segment (Parameters) isn't used, the name and numTimes parameters are passed as query strings. 上述 URL 中的 ? (問號) 是分隔符號,隨後接著查詢字串。The ? (question mark) in the above URL is a separator, and the query strings follow. & 字元可分隔查詢字串。The & character separates query strings.

以下列程式碼取代 Welcome 方法:Replace the Welcome method with the following code:

public string Welcome(string name, int ID = 1)
{
    return HtmlEncoder.Default.Encode($"Hello {name}, ID: {ID}");
}

執行應用程式,並輸入下列 URL:https://localhost:xxx/HelloWorld/Welcome/3?name=RickRun the app and enter the following URL: https://localhost:xxx/HelloWorld/Welcome/3?name=Rick

此時,第三個 URL 區段符合路由參數 idThis time the third URL segment matched the route parameter id. Welcome 方法包含符合 MapRoute 方法中 URL 範本的 id 參數。The Welcome method contains a parameter id that matched the URL template in the MapRoute method. 結尾的 ? (在 id? 中) 表示 id 是選擇性參數。The trailing ? (in id?) indicates the id parameter is optional.

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

在這些範例中,控制器已執行 MVC 的 "VC" 部分,也就是檢視和控制器工作。In these examples the controller has been doing the "VC" portion of MVC - that is, the view and controller work. 控制器會直接傳回 HTML。The controller is returning HTML directly. 一般來說,您不希望控制器直接傳回 HTML,因為撰寫程式碼和維護會變得很麻煩。Generally you don't want controllers returning HTML directly, since that becomes very cumbersome to code and maintain. 相反地,您通常使用個別的 Razor 檢視範本檔案來協助產生 HTML 回應。Instead you typically use a separate Razor view template file to help generate the HTML response. 您可在接下來的教學課程中這麼做。You do that in the next tutorial.