和我們學習Asp.Net MVC一樣,Asp.Net Core MVC的Model、View、Controller也和我們熟悉的Asp.Net MVC中的相似。不同的是我們在使用Asp.Net Core MVC的時候需要注入MVC。
Asp.Net Core MVC注入 MVC 的方法有兩種,一種是AddMvcCore(),它只是注入了MVC的一些核心的東西,不包括像返回的ViewResult、JsonResult等,如果要使用完整的MVC,需要使用另一種注入方式 AddMvc() 進行注入,AddMvc()里調用了AddMvcCore()。
下面我們就來詳細說說模型、視圖、控制器。
我們新建完一個MVC項目后,模板幫我們生成了Models、Views、Controllers三個文件夾,一般我們把新建的Model放在Models中,但實際項目上我們通常會新建一個項目放model。
MVC 中的模型包含一組表示數據的類和管理該數據的邏輯。View和Controller之間可以通過Model來傳遞數據。 我們定義一個學生類,一個學生倉儲接口還有一個該接口的實現。
/// <summary> /// 學生模型 /// </summary> public class Student { public int Id { get; set; } public string Name { get; set; } public string ClassName { get; set; } public string Email { get; set; } }
public interface IStudentRepository { Student GetStudent(int id); }
public class MockStudentRepository : IStudentRepository { private List<Student> _studentList; public MockStudentRepository() { _studentList = new List<Student>(); _studentList.AddRange(new List<Student>() { new Student(){Id=1,Name="張三",ClassName="三年一班",Email="zhangshang@qq.com"}, new Student(){Id=2,Name="李四",ClassName="三年一班",Email="zhangshang@qq.com"}, new Student(){Id=3,Name="王五",ClassName="三年一班",Email="zhangshang@qq.com"}, new Student(){Id=4,Name="趙六",ClassName="三年一班",Email="zhangshang@qq.com"}, new Student(){Id=5,Name="錢七",ClassName="三年一班",Email="zhangshang@qq.com"}, }); } public Student GetStudent(int id) { return _studentList.Where(s => s.Id == id).FirstOrDefault(); } }
新建一個HomeController,添加代碼
private readonly IStudentRepository _studentRepository; //構造函數注入 public HomeController(IStudentRepository studentRepository) { _studentRepository = studentRepository; } public IActionResult Index(int id) { return View(_studentRepository.GetStudent(id)); }
添加視圖Index.cshtml
@model StudentManagement.Models.Student @{ ViewData["Title"] = "Index"; } <div> @Model.Id @Model.Name @Model.ClassName @Model.Email </div>
我們可以看到,Controller通過Repository獲取到Student的數據后將其作為View的參數返回了,而在視圖Index我們可以使用@model StudentManagement.Models.Student來引用模型。
當然,將數據傳遞到視圖還有其他的方式,這一點和我們在Asp.Net MVC的時候是一樣的,我們可以總結一下:
1、ViewData:弱類型的字典對象,使用string類型的鍵值對,運行時動態解析,沒有智能感知,編譯也沒有檢查類型。
2、ViewBag:ViewData的包裝器,都創建了一個弱類型的視圖,使用動態屬性來存儲和查詢數據。
3、強類型視圖:在視圖中使用@model指令指定模型類型,使用@Model訪問模型對象屬性,提供編譯類型檢查和智能提示。
需要注意的是,在我們HomeController的構造函數里,形參 IIStudentRepository 是怎么傳入的呢?我們知道Asp.Net Core自帶了依賴注入容器,在前面講Startup文件時候知道ConfigureServices方法是用來注入服務的,所以我們需要將我們的 IIStudentRepository 注入進去,否則運行會拋異常。
services.AddTransient<IStudentRepository, MockStudentRepository>();
在返回VIew的時候,上面例子我們傳了一個model作為參數,實際上它也可以傳遞視圖名稱,在傳遞視圖名稱的時候可以使用絕對路徑或相對路徑,絕對路徑必須指定.cshtml文件擴展名,相對路徑不用帶擴展名.cshtml。
我們定義一個Detail視圖,然后調用return View("Detail")
public ObjectResult Detail() { return new ObjectResult(_studentRepository.GetStudent(1)); }
return View("Detail");
我們使用的是相對路徑,那么.Net Core會執行下面的操作去查找視圖
1、在“/ Views / Home /”文件夾中查找,找到就返回,找不到繼續往第2步找。
2、在“/ Views / Shared /”文件夾中查找,找到就返回,找不到繼續往第3步找。
3、在“/ Pages / Shared /”文件夾中查找, 如果找到視圖文件,則視圖生成的 HTML 將發送回發出請求的客戶端。如果找不到視圖文件,將收到錯誤。
The view 'Detail' was not found
最后,講一下ViewModel模型視圖的一個概念,很多時候我們的視圖需要的數據往往比我們定義的Model能提供的數據要多,這時候就可以使用ViewModel了,在實際項目開發中,ViewModel也等於DTO(數據傳輸對象)。至於ViewModel的使用和Model一樣,傳遞到View中進行顯示。