Tôi chưa quen với ASP.NET MVC. Tôi có một vấn đề với việc hiểu mục đích của ViewModel.
ViewModel là gì và tại sao chúng ta cần ViewModel cho ứng dụng ASP.NET MVC?
Nếu tôi có được một ví dụ tốt về hoạt động và giải thích của nó sẽ tốt hơn.
Tôi chưa quen với ASP.NET MVC. Tôi có một vấn đề với việc hiểu mục đích của ViewModel.
ViewModel là gì và tại sao chúng ta cần ViewModel cho ứng dụng ASP.NET MVC?
Nếu tôi có được một ví dụ tốt về hoạt động và giải thích của nó sẽ tốt hơn.
Câu trả lời:
A view model
đại diện cho dữ liệu bạn muốn hiển thị trên chế độ xem / trang của bạn, cho dù nó được sử dụng cho văn bản tĩnh hoặc cho các giá trị đầu vào (như hộp văn bản và danh sách thả xuống) có thể được thêm vào cơ sở dữ liệu (hoặc chỉnh sửa). Nó là một cái gì đó khác với của bạn domain model
. Nó là một mô hình cho quan điểm.
Giả sử bạn có một Employee
lớp đại diện cho mô hình miền nhân viên của bạn và nó chứa các thuộc tính sau (mã định danh duy nhất, tên, họ và ngày được tạo):
public class Employee : IEntity
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateCreated { get; set; }
}
Các mô hình xem khác với các mô hình miền trong các mô hình xem đó chỉ chứa dữ liệu (được biểu thị bằng các thuộc tính) mà bạn muốn sử dụng trên chế độ xem của mình. Ví dụ: giả sử bạn muốn thêm một bản ghi nhân viên mới, mô hình xem của bạn có thể trông như thế này:
public class CreateEmployeeViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Như bạn có thể thấy nó chỉ chứa hai trong số các thuộc tính. Hai thuộc tính này cũng nằm trong mô hình miền nhân viên. Tại sao điều này bạn có thể hỏi? Id
có thể không được đặt từ chế độ xem, nó có thể được tạo tự động bởi bảng Nhân viên. Và DateCreated
cũng có thể được đặt trong thủ tục được lưu trữ hoặc trong lớp dịch vụ của ứng dụng của bạn. Vì vậy Id
và DateCreated
không cần thiết trong mô hình xem. Bạn có thể muốn hiển thị hai thuộc tính này khi bạn xem chi tiết của nhân viên (một nhân viên đã bị bắt) dưới dạng văn bản tĩnh.
Khi tải chế độ xem / trang, phương thức tạo hành động trong bộ điều khiển nhân viên của bạn sẽ tạo một phiên bản của mô hình chế độ xem này, điền vào bất kỳ trường nào nếu được yêu cầu và sau đó chuyển mô hình xem này cho chế độ xem / trang:
public class EmployeeController : Controller
{
private readonly IEmployeeService employeeService;
public EmployeeController(IEmployeeService employeeService)
{
this.employeeService = employeeService;
}
public ActionResult Create()
{
CreateEmployeeViewModel model = new CreateEmployeeViewModel();
return View(model);
}
public ActionResult Create(CreateEmployeeViewModel model)
{
// Do what ever needs to be done before adding the employee to the database
}
}
Chế độ xem / trang của bạn có thể trông như thế này (giả sử bạn đang sử dụng ASP.NET MVC
và Razor
công cụ xem):
@model MyProject.Web.ViewModels.CreateEmployeeViewModel
<table>
<tr>
<td><b>First Name:</b></td>
<td>@Html.TextBoxFor(m => m.FirstName, new { maxlength = "50", size = "50" })
@Html.ValidationMessageFor(m => m.FirstName)
</td>
</tr>
<tr>
<td><b>Last Name:</b></td>
<td>@Html.TextBoxFor(m => m.LastName, new { maxlength = "50", size = "50" })
@Html.ValidationMessageFor(m => m.LastName)
</td>
</tr>
</table>
Xác nhận do đó sẽ chỉ được thực hiện trên FirstName
và LastName
. Sử dụng FluentValidation bạn có thể có xác nhận như thế này:
public class CreateEmployeeViewModelValidator : AbstractValidator<CreateEmployeeViewModel>
{
public CreateEmployeeViewModelValidator()
{
RuleFor(m => m.FirstName)
.NotEmpty()
.WithMessage("First name required")
.Length(1, 50)
.WithMessage("First name must not be greater than 50 characters");
RuleFor(m => m.LastName)
.NotEmpty()
.WithMessage("Last name required")
.Length(1, 50)
.WithMessage("Last name must not be greater than 50 characters");
}
}
Và với Chú thích dữ liệu, nó có thể trông như thế này:
public class CreateEmployeeViewModel : ViewModelBase
{
[Display(Name = "First Name")]
[Required(ErrorMessage = "First name required")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
[Required(ErrorMessage = "Last name required")]
public string LastName { get; set; }
}
Điều quan trọng cần nhớ là mô hình khung nhìn chỉ đại diện cho dữ liệu mà bạn muốn sử dụng , không có gì khác. Bạn có thể tưởng tượng tất cả các mã và xác nhận không cần thiết nếu bạn có một mô hình miền với 30 thuộc tính và bạn chỉ muốn cập nhật một giá trị duy nhất. Với kịch bản này, bạn sẽ chỉ có một giá trị / thuộc tính này trong mô hình khung nhìn và không phải tất cả các thuộc tính có trong đối tượng miền.
Một mô hình xem có thể không chỉ có dữ liệu từ một bảng cơ sở dữ liệu. Nó có thể kết hợp dữ liệu từ một bảng khác. Lấy ví dụ của tôi ở trên về việc thêm một hồ sơ nhân viên mới. Bên cạnh việc chỉ thêm tên và họ, bạn cũng có thể muốn thêm bộ phận của nhân viên. Danh sách các phòng ban sẽ đến từ Departments
bảng của bạn . Vì vậy, bây giờ bạn có dữ liệu từ Employees
và Departments
bảng trong một mô hình xem. Sau đó, bạn sẽ cần thêm hai thuộc tính sau vào mô hình xem của mình và điền dữ liệu vào đó:
public int DepartmentId { get; set; }
public IEnumerable<Department> Departments { get; set; }
Khi chỉnh sửa dữ liệu nhân viên (một nhân viên đã được thêm vào cơ sở dữ liệu), nó sẽ không khác nhiều so với ví dụ của tôi ở trên. Tạo một mô hình xem, gọi nó là ví dụ EditEmployeeViewModel
. Chỉ có dữ liệu mà bạn muốn chỉnh sửa trong mô hình chế độ xem này, như tên và họ. Chỉnh sửa dữ liệu và nhấp vào nút gửi. Tôi sẽ không lo lắng quá nhiều về Id
lĩnh vực này vì Id
giá trị có thể sẽ nằm trong URL, ví dụ:
http://www.yourwebsite.com/Employee/Edit/3
Lấy cái này Id
và chuyển nó qua lớp kho lưu trữ của bạn, cùng với các giá trị tên và họ của bạn.
Khi xóa một bản ghi, tôi thường đi theo cùng một đường dẫn như với mô hình xem chỉnh sửa. Tôi cũng sẽ có một URL, ví dụ:
http://www.yourwebsite.com/Employee/Delete/3
Khi chế độ xem tải lên lần đầu tiên, tôi sẽ lấy dữ liệu của nhân viên từ cơ sở dữ liệu bằng cách sử dụng Id
số 3. Tôi sẽ chỉ hiển thị văn bản tĩnh trên chế độ xem / trang của mình để người dùng có thể thấy nhân viên nào đang bị xóa. Khi người dùng nhấp vào nút Xoá, tôi sẽ chỉ sử dụng Id
giá trị 3 và chuyển nó vào lớp kho lưu trữ của mình. Bạn chỉ cần Id
xóa một bản ghi từ bảng.
Một điểm khác, bạn không thực sự cần một mô hình xem cho mọi hành động. Nếu đó là dữ liệu đơn giản thì sẽ tốt thôi nếu chỉ sử dụng EmployeeViewModel
. Nếu đó là các chế độ xem / trang phức tạp và chúng khác nhau thì tôi sẽ đề nghị bạn sử dụng các mô hình xem riêng biệt cho từng trang.
Tôi hy vọng điều này sẽ làm sáng tỏ mọi sự nhầm lẫn mà bạn có về các mô hình xem và mô hình miền.
Mô hình khung nhìn là một lớp biểu thị mô hình dữ liệu được sử dụng trong một khung nhìn cụ thể. Chúng ta có thể sử dụng lớp này làm mô hình cho trang đăng nhập:
public class LoginPageVM
{
[Required(ErrorMessage = "Are you really trying to login without entering username?")]
[DisplayName("Username/e-mail")]
public string UserName { get; set; }
[Required(ErrorMessage = "Please enter password:)")]
[DisplayName("Password")]
public string Password { get; set; }
[DisplayName("Stay logged in when browser is closed")]
public bool RememberMe { get; set; }
}
Sử dụng mô hình khung nhìn này, bạn có thể xác định chế độ xem (Công cụ xem dao cạo):
@model CamelTrap.Models.ViewModels.LoginPageVM
@using (Html.BeginForm()) {
@Html.EditorFor(m => m);
<input type="submit" value="Save" class="submit" />
}
Và hành động:
[HttpGet]
public ActionResult LoginPage()
{
return View();
}
[HttpPost]
public ActionResult LoginPage(LoginPageVM model)
{
...code to login user to application...
return View(model);
}
Cái nào tạo ra kết quả này (màn hình được lấy sau khi gửi biểu mẫu, với thông báo xác thực):
Như bạn có thể thấy, một mô hình khung nhìn có nhiều vai trò:
LabelFor
, EditorFor
, DisplayFor
những người giúp đỡ).Một ví dụ khác về mô hình khung nhìn và truy xuất mô hình: Chúng tôi muốn hiển thị dữ liệu người dùng cơ bản, đặc quyền và tên người dùng của anh ấy. Chúng tôi tạo một mô hình khung nhìn đặc biệt, chỉ chứa các trường bắt buộc. Chúng tôi lấy dữ liệu từ các thực thể khác nhau từ cơ sở dữ liệu, nhưng chế độ xem chỉ biết về lớp mô hình xem:
public class UserVM {
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool IsAdministrator { get; set; }
public string MothersName { get; set; }
}
Truy tìm:
var user = db.userRepository.GetUser(id);
var model = new UserVM() {
ID = user.ID,
FirstName = user.FirstName,
LastName = user.LastName,
IsAdministrator = user.Proviledges.IsAdministrator,
MothersName = user.Mother.FirstName + " " + user.Mother.LastName
}
Chỉnh sửa: Tôi đã cập nhật câu trả lời này trên Blog của mình:
http://www.samwheat.com/post/The-feft-of-ViewModels-in-MVC-web-development
Câu trả lời của tôi hơi dài dòng nhưng tôi nghĩ điều quan trọng là so sánh các mô hình xem với các loại mô hình thường được sử dụng khác để hiểu tại sao chúng khác nhau và tại sao chúng lại cần thiết.
Để tóm tắt và trả lời trực tiếp câu hỏi được hỏi:
Nói chung, mô hình khung nhìn là một đối tượng chứa tất cả các thuộc tính và phương thức cần thiết để hiển thị một khung nhìn. Các thuộc tính mô hình xem thường liên quan đến các đối tượng dữ liệu như khách hàng và đơn đặt hàng và ngoài ra chúng cũng chứa các thuộc tính liên quan đến trang hoặc chính ứng dụng như tên người dùng, tên ứng dụng, v.v. Các mô hình xem cung cấp một đối tượng thuận tiện để chuyển đến một công cụ kết xuất tạo một trang html. Một trong nhiều lý do để sử dụng mô hình khung nhìn là các mô hình khung nhìn cung cấp một cách để kiểm tra đơn vị một số tác vụ trình bày nhất định như xử lý dữ liệu nhập của người dùng, xác thực dữ liệu, truy xuất dữ liệu để hiển thị, v.v.
Dưới đây là so sánh các mô hình Thực thể (mô hình a.ka. a.ka. của DTO), Mô hình trình bày và Mô hình xem.
Đối tượng truyền dữ liệu hay còn gọi là Model Model
Đối tượng truyền dữ liệu (DTO) là một lớp có các thuộc tính khớp với lược đồ bảng trong cơ sở dữ liệu. DTO được đặt tên theo cách sử dụng phổ biến của họ để chuyển dữ liệu đến và từ một cửa hàng dữ liệu.
Đặc điểm của DTO:
• Là đối tượng kinh doanh - định nghĩa của chúng phụ thuộc vào dữ liệu ứng dụng.
• Thường chỉ chứa các thuộc tính - không có mã.
• Chủ yếu được sử dụng để vận chuyển dữ liệu đến và từ cơ sở dữ liệu.
• Thuộc tính chính xác hoặc khớp các trường trên một bảng cụ thể trong kho lưu trữ dữ liệu.
Các bảng cơ sở dữ liệu thường được chuẩn hóa do đó các DTO thường cũng được chuẩn hóa. Điều này làm cho chúng được sử dụng hạn chế để trình bày dữ liệu. Tuy nhiên, đối với các cấu trúc dữ liệu đơn giản nhất định, chúng thường làm khá tốt.
Đây là hai ví dụ về hình dạng của DTO:
public class Customer
{
public int ID { get; set; }
public string CustomerName { get; set; }
}
public class Order
{
public int ID { get; set; }
public int CustomerID { get; set; }
public DateTime OrderDate { get; set; }
public Decimal OrderAmount { get; set; }
}
Mô hình trình bày
Mô hình trình bày là một lớp tiện ích được sử dụng để hiển thị dữ liệu trên màn hình hoặc báo cáo. Các mô hình trình bày thường được sử dụng để mô hình các cấu trúc dữ liệu phức tạp được tạo từ dữ liệu từ nhiều DTO. Các mô hình trình bày thường đại diện cho một cái nhìn không chuẩn hóa dữ liệu.
Đặc điểm của mô hình trình bày:
• Là đối tượng kinh doanh - định nghĩa của chúng phụ thuộc vào dữ liệu ứng dụng.
• Chứa hầu hết các thuộc tính. Mã thường được giới hạn trong việc định dạng dữ liệu hoặc chuyển đổi sang hoặc từ DTO. Mô hình trình bày không nên chứa logic kinh doanh.
• Thường trình bày một cái nhìn không chuẩn hóa dữ liệu. Đó là, họ thường kết hợp các thuộc tính từ nhiều DTO.
• Thường chứa các thuộc tính của loại cơ sở khác với DTO. Ví dụ, số tiền có thể được biểu diễn dưới dạng chuỗi để chúng có thể chứa dấu phẩy và ký hiệu tiền tệ.
• Thường được xác định bởi cách chúng được sử dụng cũng như các đặc điểm đối tượng của chúng. Nói cách khác, một DTO đơn giản được sử dụng làm mô hình sao lưu để hiển thị lưới trên thực tế cũng là một mô hình trình bày trong ngữ cảnh của lưới đó.
Các mô hình trình bày được sử dụng, khi cần thiết và các nơi cần thiết (trong khi DTO thường được gắn với lược đồ cơ sở dữ liệu). Một mô hình trình bày có thể được sử dụng để mô hình hóa dữ liệu cho toàn bộ trang, lưới trên một trang hoặc thả xuống trên lưới trên một trang. Các mô hình trình bày thường chứa các thuộc tính là các mô hình trình bày khác. Các mô hình trình bày thường được xây dựng cho một mục đích sử dụng duy nhất như để hiển thị một lưới cụ thể trên một trang.
Một mô hình trình bày ví dụ:
public class PresentationOrder
{
public int OrderID { get; set; }
public DateTime OrderDate { get; set; }
public string PrettyDate { get { return OrderDate.ToShortDateString(); } }
public string CustomerName { get; set; }
public Decimal OrderAmount { get; set; }
public string PrettyAmount { get { return string.Format("{0:C}", OrderAmount); } }
}
Xem mô hình
Mô hình khung nhìn tương tự như mô hình trình bày trong đó là lớp hỗ trợ để hiển thị chế độ xem. Tuy nhiên, nó rất khác với Mô hình trình bày hoặc DTO về cách thức xây dựng nó. Các mô hình xem thường chứa các thuộc tính giống như các mô hình trình bày và của DTO và vì lý do này, chúng thường bị nhầm lẫn với nhau.
Đặc điểm của mô hình xem:
• Là nguồn dữ liệu duy nhất được sử dụng để hiển thị trang hoặc màn hình. Thông thường, điều này có nghĩa là một mô hình chế độ xem sẽ hiển thị mọi thuộc tính mà mọi điều khiển trên trang sẽ cần hiển thị chính xác. Làm cho mô hình khung nhìn trở thành nguồn dữ liệu duy nhất cho khung nhìn giúp cải thiện đáng kể khả năng và giá trị của nó cho thử nghiệm đơn vị.
• Là các đối tượng tổng hợp có chứa các thuộc tính bao gồm dữ liệu ứng dụng cũng như các thuộc tính được sử dụng bởi mã ứng dụng. Đặc tính này rất quan trọng khi thiết kế mô hình khung nhìn cho khả năng sử dụng lại và được thảo luận trong các ví dụ dưới đây.
• Chứa mã ứng dụng. Mô hình xem thường chứa các phương thức được gọi trong khi kết xuất và khi người dùng tương tác với trang. Mã này thường liên quan đến xử lý sự kiện, hoạt hình, khả năng hiển thị của các điều khiển, kiểu dáng, v.v.
• Chứa mã gọi các dịch vụ kinh doanh cho mục đích lấy dữ liệu hoặc gửi nó đến một máy chủ cơ sở dữ liệu. Mã này thường bị đặt nhầm trong bộ điều khiển. Gọi các dịch vụ kinh doanh từ bộ điều khiển thường giới hạn tính hữu ích của mô hình xem để thử nghiệm đơn vị. Để rõ ràng, bản thân các mô hình xem không nên chứa logic nghiệp vụ mà nên thực hiện các cuộc gọi đến các dịch vụ có chứa logic nghiệp vụ.
• Thường chứa các thuộc tính là các mô hình xem khác cho các trang hoặc màn hình khác.
• Được viết trên mỗi trang Tử hoặc trên mỗi màn hình. Mô hình Chế độ xem duy nhất thường được viết cho mọi trang hoặc màn hình trong một ứng dụng.
• Thường xuất phát từ một lớp cơ sở vì hầu hết các trang và màn hình chia sẻ các thuộc tính chung.
Xem thành phần mô hình
Như đã nêu trước đó, các mô hình xem là các đối tượng tổng hợp trong đó chúng kết hợp các thuộc tính ứng dụng và thuộc tính dữ liệu nghiệp vụ trên một đối tượng. Ví dụ về các thuộc tính ứng dụng thường được sử dụng trên các mô hình xem là:
• Các thuộc tính được sử dụng để hiển thị trạng thái ứng dụng như thông báo lỗi, tên người dùng, trạng thái, v.v.
• Thuộc tính được sử dụng để định dạng, hiển thị, cách điệu hoặc điều khiển hoạt hình.
• Thuộc tính được sử dụng để liên kết dữ liệu, chẳng hạn như liệt kê các đối tượng và thuộc tính chứa dữ liệu trung gian được người dùng nhập vào.
Các ví dụ sau đây cho thấy lý do tại sao tính chất tổng hợp của các mô hình xem là quan trọng và làm thế nào chúng ta có thể xây dựng Mô hình Chế độ xem hiệu quả và có thể tái sử dụng tốt nhất.
Giả sử chúng ta đang viết một ứng dụng web. Một trong những yêu cầu của thiết kế ứng dụng là tiêu đề trang, tên người dùng và tên ứng dụng phải được hiển thị trên mỗi trang. Nếu chúng tôi muốn tạo một trang để hiển thị một đối tượng thứ tự trình bày, chúng tôi có thể sửa đổi mô hình trình bày như sau:
public class PresentationOrder
{
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
public int OrderID { get; set; }
public DateTime OrderDate { get; set; }
public string PrettyDate { get { return OrderDate.ToShortDateString(); } }
public string CustomerName { get; set; }
public Decimal OrderAmount { get; set; }
public string PrettyAmount { get { return string.Format("{0:C}", OrderAmount); } }
}
Thiết kế này có thể hoạt động được nhưng nếu chúng ta muốn tạo một trang sẽ hiển thị danh sách các đơn đặt hàng thì sao? Các thuộc tính PageTitle, UserName và ApplicationName sẽ được lặp lại và trở nên khó sử dụng. Ngoài ra, nếu chúng ta muốn định nghĩa một số logic cấp độ trang trong hàm tạo của lớp thì sao? Chúng tôi không còn có thể làm điều đó nếu chúng tôi tạo một phiên bản cho mỗi đơn hàng sẽ được hiển thị.
Thành phần trên thừa kế
Dưới đây là cách chúng ta có thể xác định lại mô hình trình bày thứ tự để nó trở thành mô hình khung nhìn thực và sẽ hữu ích để hiển thị một đối tượng PresentationOrder hoặc một bộ sưu tập các đối tượng PresentationOrder:
public class PresentationOrderVM
{
// Application properties
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
// Business properties
public PresentationOrder Order { get; set; }
}
public class PresentationOrderVM
{
// Application properties
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
// Business properties
public List<PresentationOrder> Orders { get; set; }
}
Nhìn vào hai lớp ở trên, chúng ta có thể thấy rằng một cách để suy nghĩ về một mô hình khung nhìn là nó là một mô hình trình bày có chứa một mô hình trình bày khác như một thuộc tính. Mô hình trình bày cấp cao nhất (ví dụ mô hình xem) chứa các thuộc tính có liên quan đến trang hoặc ứng dụng trong khi mô hình trình bày (thuộc tính) chứa các thuộc tính có liên quan đến dữ liệu ứng dụng.
Chúng ta có thể tiến lên một bước nữa và tạo ra một lớp mô hình khung nhìn cơ sở có thể được sử dụng không chỉ cho PresentationOrder, mà còn cho bất kỳ lớp nào khác:
public class BaseViewModel
{
// Application properties
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
}
Bây giờ chúng ta có thể đơn giản hóa PresentationOrderVM của mình như thế này:
public class PresentationOrderVM : BaseViewModel
{
// Business properties
public PresentationOrder Order { get; set; }
}
public class PresentationOrderVM : BaseViewModel
{
// Business properties
public List<PresentationOrder> Orders { get; set; }
}
Chúng tôi có thể làm cho BaseViewModel của chúng tôi có thể sử dụng lại nhiều hơn bằng cách đặt nó chung chung:
public class BaseViewModel<T>
{
// Application properties
public string PageTitle { get; set; }
public string UserName { get; set; }
public string ApplicationName { get; set; }
// Business property
public T BusinessObject { get; set; }
}
Bây giờ việc thực hiện của chúng tôi là dễ dàng:
public class PresentationOrderVM : BaseViewModel<PresentationOrder>
{
// done!
}
public class PresentationOrderVM : BaseViewModel<List<PresentationOrder>>
{
// done!
}
MyViewModel<MyPresModel>
Nếu bạn có các thuộc tính cụ thể cho chế độ xem và không liên quan đến kho lưu trữ DB / Dịch vụ / Dữ liệu, thì nên sử dụng ViewModels. Giả sử, bạn muốn để lại một hộp kiểm được chọn dựa trên trường DB (hoặc hai) nhưng bản thân trường DB không phải là boolean. Mặc dù có thể tạo các thuộc tính này trong Mô hình và giữ nó ẩn khỏi ràng buộc với dữ liệu, bạn có thể không muốn làm lộn xộn Mô hình tùy thuộc vào số lượng các trường và giao dịch đó.
Nếu có quá ít dữ liệu và / hoặc biến đổi chế độ xem cụ thể, bạn có thể sử dụng chính Mô hình
Tôi đã không đọc tất cả các bài viết nhưng mọi câu trả lời dường như thiếu một khái niệm thực sự giúp tôi "hiểu" ...
Nếu một Mô hình gần giống với Bảng cơ sở dữ liệu , thì ViewModel gần giống với Cơ sở dữ liệu Xem - Một khung nhìn thường trả về một lượng nhỏ dữ liệu từ một bảng hoặc, các bộ dữ liệu phức tạp từ nhiều bảng (tham gia).
Tôi thấy mình đang sử dụng ViewModels để chuyển thông tin vào dạng xem / biểu mẫu và sau đó chuyển dữ liệu đó thành Mô hình hợp lệ khi biểu mẫu gửi lại cho bộ điều khiển - cũng rất tiện để lưu trữ Danh sách (IEnumerable).
MVC không có viewmodel: nó có mô hình, khung nhìn và bộ điều khiển. Một viewmodel là một phần của MVVM (Model-View-Viewmodel). MVVM có nguồn gốc từ Mô hình trình bày và được phổ biến trong WPF. Cũng cần có một mô hình trong MVVM, nhưng hầu hết mọi người đều bỏ lỡ hoàn toàn điểm của mẫu đó và họ sẽ chỉ có chế độ xem và chế độ xem. Mô hình trong MVC tương tự như mô hình trong MVVM.
Trong MVC, quy trình được chia thành 3 trách nhiệm khác nhau:
MVC không phù hợp lắm cho các ứng dụng web. Đó là một mẫu được giới thiệu bởi Smalltalk để tạo các ứng dụng máy tính để bàn. Một môi trường web hoạt động hoàn toàn khác nhau. Sẽ không có ý nghĩa gì khi sao chép một khái niệm 40 năm tuổi từ sự phát triển máy tính để bàn và dán nó vào một môi trường web. Tuy nhiên, rất nhiều người nghĩ rằng điều này là ổn, bởi vì ứng dụng của họ biên dịch và trả về các giá trị chính xác. Đó là, theo tôi, không đủ để tuyên bố một sự lựa chọn thiết kế nhất định là ok.
Một ví dụ về mô hình trong ứng dụng web có thể là:
public class LoginModel
{
private readonly AuthenticationService authentication;
public LoginModel(AuthenticationService authentication)
{
this.authentication = authentication;
}
public bool Login()
{
return authentication.Login(Username, Password);
}
public string Username { get; set; }
public string Password { get; set; }
}
Bộ điều khiển có thể sử dụng nó như thế này:
public class LoginController
{
[HttpPost]
public ActionResult Login(LoginModel model)
{
bool success = model.Login();
if (success)
{
return new RedirectResult("/dashboard");
}
else
{
TempData["message"] = "Invalid username and/or password";
return new RedirectResult("/login");
}
}
}
Các phương thức điều khiển và mô hình của bạn sẽ nhỏ, dễ kiểm tra và đi vào điểm chính.
Xem mô hình a là lớp đơn giản có thể chứa nhiều thuộc tính lớp. Chúng tôi sử dụng nó để kế thừa tất cả các thuộc tính cần thiết, ví dụ: tôi có hai lớp Sinh viên và Chủ đề
Public class Student
{
public int Id {get; set;}
public string Name {get; set;}
}
Public class Subject
{
public int SubjectID {get; set;}
public string SubjectName {get; set;}
}
Bây giờ chúng tôi muốn hiển thị các bản ghi Tên và Chủ đề của sinh viên trong Chế độ xem (Trong MVC), nhưng không thể thêm nhiều hơn một lớp như:
@model ProjectName.Model.Student
@model ProjectName.Model.Subject
đoạn mã trên sẽ gây ra lỗi ...
Bây giờ chúng tôi tạo một lớp và có thể đặt cho nó bất kỳ tên nào, nhưng định dạng "XyzViewModel" này sẽ giúp bạn dễ hiểu hơn. Đó là khái niệm thừa kế. Bây giờ chúng ta tạo một lớp thứ ba với tên sau:
public class StudentViewModel:Subject
{
public int ID {get; set;}
public string Name {get; set;}
}
Bây giờ chúng tôi sử dụng ViewModel này trong View
@model ProjectName.Model.StudentViewModel
Bây giờ chúng tôi có thể truy cập tất cả các thuộc tính của StudentViewModel và lớp kế thừa trong View.
Rất nhiều ví dụ lớn, hãy để tôi giải thích một cách rõ ràng và giòn.
ViewModel = Model được tạo để phục vụ cho view.
Chế độ xem ASP.NET MVC không thể có nhiều hơn một mô hình vì vậy nếu chúng ta cần hiển thị các thuộc tính từ nhiều hơn một mô hình vào chế độ xem thì không thể. ViewModel phục vụ mục đích này.
Mô hình khung nhìn là một lớp mô hình chỉ có thể chứa các thuộc tính được yêu cầu cho một khung nhìn. Nó cũng có thể chứa các thuộc tính từ nhiều hơn một thực thể (bảng) của cơ sở dữ liệu. Như tên cho thấy, mô hình này được tạo cụ thể cho các yêu cầu Xem.
Một số ví dụ về Mô hình xem bên dưới
ViewModel cũng có thể được sử dụng để chèn, cập nhật các bản ghi vào nhiều hơn một thực thể, tuy nhiên công dụng chính của ViewModel là hiển thị các cột từ nhiều thực thể (mô hình) vào một chế độ xem.
Cách tạo ViewModel giống như tạo Model, cách tạo view cho Viewmodel cũng giống như tạo view cho Model.
Đây là một ví dụ nhỏ về dữ liệu Danh sách bằng ViewModel .
Hy vọng điều này sẽ hữu ích.
ViewModel là giải pháp thay thế cho sự vụng về về mặt khái niệm của khung MVC. Nó đại diện cho lớp thứ 4 trong kiến trúc Model-View-Controller 3 lớp. khi Mô hình (mô hình miền) không phù hợp, quá lớn (lớn hơn 2-3 trường) cho Chế độ xem, chúng tôi tạo ViewModel nhỏ hơn để chuyển nó sang Chế độ xem.
Một mô hình xem là một mô hình khái niệm của dữ liệu. Ví dụ, việc sử dụng nó là lấy một tập hợp con hoặc kết hợp dữ liệu từ các bảng khác nhau.
Bạn có thể chỉ muốn các thuộc tính cụ thể, vì vậy điều này cho phép bạn chỉ tải các thuộc tính đó chứ không phải các thuộc tính không cần thiết bổ sung
Thiết kế ViewModel
public class UserLoginViewModel
{
[Required(ErrorMessage = "Please enter your username")]
[Display(Name = "User Name")]
[MaxLength(50)]
public string UserName { get; set; }
[Required(ErrorMessage = "Please enter your password")]
[Display(Name = "Password")]
[MaxLength(50)]
public string Password { get; set; }
}
Trình bày viewmodel trong khung nhìn
@model MyModels.UserLoginViewModel
@{
ViewBag.Title = "User Login";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
<div class="editor-label">
@Html.LabelFor(m => m.UserName)
</div>
<div class="editor-field">
@Html.TextBoxFor(m => m.UserName)
@Html.ValidationMessageFor(m => m.UserName)
</div>
<div class="editor-label">
@Html.LabelFor(m => m.Password)
</div>
<div class="editor-field">
@Html.PasswordFor(m => m.Password)
@Html.ValidationMessageFor(m => m.Password)
</div>
<p>
<input type="submit" value="Log In" />
</p>
</div>
}
Làm việc với hành động
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(UserLoginViewModel user)
{
// To acces data using LINQ
DataClassesDataContext mobjentity = new DataClassesDataContext();
if (ModelState.IsValid)
{
try
{
var q = mobjentity.tblUsers.Where(m => m.UserName == user.UserName && m.Password == user.Password).ToList();
if (q.Count > 0)
{
return RedirectToAction("MyAccount");
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
catch (Exception ex)
{
}
}
return View(user);
}
View Model là lớp mà chúng ta có thể sử dụng để hiển thị dữ liệu trên View. Giả sử bạn có hai thực thể Place và PlaceC Category và bạn muốn truy cập dữ liệu từ cả hai thực thể bằng một mô hình duy nhất thì chúng tôi sử dụng ViewModel.
public class Place
{
public int PlaceId { get; set; }
public string PlaceName { get; set; }
public string Latitude { get; set; }
public string Longitude { get; set; }
public string BestTime { get; set; }
}
public class Category
{
public int ID { get; set; }
public int? PlaceId { get; set; }
public string PlaceCategoryName { get; set; }
public string PlaceCategoryType { get; set; }
}
public class PlaceCategoryviewModel
{
public string PlaceName { get; set; }
public string BestTime { get; set; }
public string PlaceCategoryName { get; set; }
public string PlaceCategoryType { get; set; }
}
Vì vậy, ở trên Ví dụ Địa điểm và Danh mục là hai thực thể khác nhau và chế độ xem PlaceC Category là ViewModel mà chúng ta có thể sử dụng trên View.
Nếu bạn muốn nghiên cứu mã làm thế nào để thiết lập ứng dụng web "Đường cơ sở" với ViewModels, tôi có thể khuyên bạn nên tải xuống mã này trên GitHub: https://github.com/ajsaulsberry/BlipAjax . Tôi đã phát triển các ứng dụng doanh nghiệp lớn. Khi bạn làm điều này có vấn đề để thiết lập một kiến trúc tốt xử lý tất cả chức năng "ViewModel" này. Tôi nghĩ với BlipAjax, bạn sẽ có một "đường cơ sở" rất tốt để bắt đầu. Nó chỉ là một trang web đơn giản, nhưng tuyệt vời trong sự đơn giản của nó. Tôi thích cách họ sử dụng ngôn ngữ tiếng Anh để chỉ ra những gì thực sự cần thiết trong ứng dụng.