問題
如何在ASP.NET Core 2.0中使用檢視元件?
答案
新建一個空專案,修改Startup類並新增MVC服務和中介軟體:
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
新增一個模型類:
public class UserInfoViewModel { public int UserId { get; set; } public string UserName { get; set; } public string LastLogin { get; set; } }
新增繼承自ViewComponent的自定義檢視元件:
public class UserInfoViewComponent : ViewComponent { public IViewComponentResult Invoke(int userId) { var model = new UserInfoViewModel { UserId = userId, UserName = "james@bond.com", LastLogin = DateTime.Now.ToString() }; return View(model); } }
新增檢視元件對應的檢視檔案(Views/Shared/Components/UserInfo/Default.cshtml):
@using ViewComponents.Models @model UserInfoViewModel <div style="border: 1px dotted blue; margin: 5px"> <h3>User Info</h3> <p>UserId: @Model.UserId</p> <p>UserName: @Model.UserName</p> <p>Last Login: @Model.LastLogin</p> </div>
新增一個控制器和相應的檢視檔案:
public class HomeController : Controller { public IActionResult Index() { return View(); } }
@using ViewComponents.Models <div style="border: 1px solid black; margin: 5px"> <h2>Home/Index</h2> @await Component.InvokeAsync("UserInfo", new { UserId = 5 }) </div>
現在,我們來看下解決方案的目錄層次:
執行,此時頁面顯示:
討論
檢視元件是渲染到其他檢視內部的一種特殊型別。對於重用檢視中的公共部分或者將大的檢視分隔成小元件都非常有用。
與部分檢視不同,檢視元件不依賴於控制器。它們有自己的類來控制元件用到的模型以及檢視模板來生成最終呈現的HTML/CSS。
我喜歡把它們看作是小型控制器,儘管這並不完全正確,但是有助於我們瞭解它們的用法。和控制器不同,檢視元件不處理HTTP請求,也沒有控制器的生命週期,這就意味著在檢視元件中不能使用過濾器和模型繫結。
檢視元件可以使用依賴注入,這使得它們更加強大和易於測試。
建立
有很多方法建立檢視元件,我們會討論最常用到的選項:
- 建立一個類(放到專案中的任意位置),使其繼承自抽象基類ViewComponent。
- 按照約定,請將類名以ViewComponent結尾。
- 建立一個返回IViewComponentResult的方法Invoke。
- 這個方法可以接受任意數量的引數,這些引數會在呼叫檢視元件時傳入。
- 將基類ViewComponent的方法View()作為Invoke的返回值,你也可以向其中傳入自定義模型。
- 可選的,你也可以在引數中指定檢視頁面的名稱。
基類ViewComponent通過屬性公開了很多有用的細節,比如HttpContext,RouteData,IUrlHelper,IPrincipal和ViewData。
呼叫
可以通過兩種方式呼叫檢視元件:
- 在檢視頁面中呼叫@await Component.InvokeAsync(component, parameters)
- 在控制器方法中,返回ViewComponent(component, parameters)
上面呼叫中的component是一個指向元件類的字串。
當呼叫檢視元件時,InvokeAsync()方法可以接受任意數量的引數,這些引數可以通過匿名物件傳入。
發現
ASP.NET Core會按照如下順序查詢檢視元件的Razor頁面:
- Views/[controller]/Components/[component]/[view].cshtml
- Views/Shared/Components/[component]/[view].cshtml
其中[component]匹配如下規則:
- 除去ViewComponent字尾的元件名。
- 檢視元件類上面[ViewComponent]特性所指定的值
其中[view]預設值是Default,當然我們也可以在檢視元件的Invoke方法中返回特定的值。比如下面的元件指定檢視名稱為MyInfo.cshtml:
public IViewComponentResult Invoke(int userId) { var model = new UserInfoViewModel { UserId = userId, UserName = "james@bond.com", LastLogin = DateTime.Now.ToString() }; return View("MyInfo", model); }
本例中,如果我們刪除檢視元件對應的Razor頁面,此時會有異常,從而我們能夠清楚看到系統的查詢順序:
原始碼下載
原文:https://tahirnaushad.com/2017/08/24/asp-net-core-2-0-mvc-view-components/