5

Giả sử chúng ta có như sau (quá đơn giản) Kịch bản:kiến ​​trúc MVC --tái sử dụng viewmodel tương tự cho đọc và chỉnh sửa

Chúng tôi có một màn hình để xem chi tiết người và một màn hình để chỉnh sửa chi tiết người.

Màn hình hiển thị màn hình chi tiết người đều có các lĩnh vực sau (như chỉ hiển thị):

Tên Họ Bio

Màn hình chỉnh sửa người chi tiết chương trình có các trường (trong điều khiển đầu vào) như sau:

ID (ẩn) Tên Họ Bio

Say dis của chúng tôi chơi viewmodel trông như thế này:

public class DisplayPersonViewModel 
    { 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public string Bio { get; set; } 
    } 

Và chỉnh sửa viewmodel của chúng tôi trông như thế này:

chênh lệch
public class EditPersonViewModel 
{ 
    [Required] 
    public int ID { get; set; } 

    [Required] 
    [StringLength(20)] 
    public string FirstName { get; set; } 

    [Required] 
    [StringLength(20)] 
    public string LastName { get; set; } 

    [Required] 
    public string Bio { get; set; } 
} 

Không có nhiều giữa 2, eh? Mô hình chỉnh sửa có thêm một trường (ID) và một số thuộc tính trên các thuộc tính. Bây giờ, nếu chúng ta kết hợp 2 như thế này:

public class DisplayPersonViewModel 
    { 
     [Required] 
     [StringLength(20)] 
     public string FirstName { get; set; } 

     [Required] 
     [StringLength(20)] 
     public string LastName { get; set; } 

     [Required] 
     public string Bio { get; set; } 
    } 

    public class EditPersonViewModel : DisplayPersonViewModel 
    { 
     [Required] 
     public int ID { get; set; } 
    } 

Điều này chắc chắn là DRY hơn, vì chúng ta không có các trường trùng lặp để duy trì, nhưng bây giờ chúng tôi có thông tin không liên quan (thuộc tính) trên viewmodel trưng bày của chúng tôi. Tôi đang nghiêng về phía phương pháp thứ hai, bất kể, bởi vì một số màn hình của chúng tôi có hơn 25 trường! (... và đó là ngoài tầm kiểm soát của tôi, vì vậy xin vui lòng không harp trên nó :) ...) Tuy nhiên, tôi chỉ muốn nghe ý kiến ​​để có được một cảm giác tốt hơn về những gì có thể là "thực hành tốt nhất".

+0

Vâng, điều gì sẽ xảy ra nếu bạn đang làm việc trên một ứng dụng lớn với nhiều mô hình có thể có nhiều hơn một hoặc nhiều trường trong mỗi ứng dụng? Và khi ứng dụng phát triển, bạn tiếp tục thêm các trường. Làm cách nào để giữ nhiều chế độ xem cho bản chất của cùng một thực thể được đồng bộ hóa theo thời gian? – DOK

Trả lời

4

Có, cách tiếp cận thứ hai có vẻ ổn với tôi. Không phải lo lắng gì khác ngoài cảm giác ngứa này trong dạ dày của bạn cho bạn biết tại sao bạn lại trang trí một kiểu xem hiển thị với các thuộc tính xác thực. Nhưng nếu bạn có thể sống với nó nó thực sự là một cái gì đó được ưa thích so với nhân bản các mô hình xem.

Thật không may là tôi không thể sống với cảm giác này trong dạ dày và đó là lý do tôi sử dụng FluentValidation.NET để xác định quy tắc xác thực thay vì chú thích dữ liệu. Nó cho phép tôi có những quy tắc riêng biệt từ các mô hình khung nhìn của tôi và sau đó tôi không lo lắng về việc gây ô nhiễm cái gọi là mô hình xem hiển thị với các quy tắc xác nhận. Vì vậy, tôi sẽ xác định theo cùng một cách như bạn xem 2 mô hình và EditPersonViewModel sẽ lấy được từ DisplayPersonViewModel và sau đó xác định EditPersonViewModelValidator của tôi cho EditPersonViewModel trong một lớp riêng biệt.

Oh và lưu ý phụ: trang trí loại không thể vô hiệu hóa với thuộc tính [Required] là không cần thiết. Tất cả các loại không thể rỗng là đều yêu cầu theo bản chất rất cơ bản của chúng. Vì vậy, thay vì:

[Required] 
public int ID { get; set; } 

bạn chỉ nên có:

public int ID { get; set; } 
+0

Vâng, tôi sẽ xem xét điều đó. Nó có hoạt động tốt với xác nhận không phô trương phía máy khách không? Ngoài ra, bạn có thể tạo trình xác thực tùy chỉnh với xác thực phía máy khách tùy chỉnh không? – drogon

+0

@drogon, nó hỗ trợ các quy tắc xác thực khách hàng giống như chú thích dữ liệu và thêm một số khác: http://fluentvalidation.codeplex.com/wikipage?title=mvc&referringTitle=Documentation –

+0

+1 cho 'cảm giác ngứa trong dạ dày' –

1

Một lựa chọn khác là sử dụng MetadataType Thuộc tính.

public class PersonModel 
{ 
    public int ID { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Bio { get; set; } 
} 

[MetadataType(typeof(IDisplayPersonViewModel))] 
public class DisplayPersonViewModel : PersonModel 

[MetadataType(typeof(IEditPersonViewModel))] 
public class EditPersonViewModel : PersonModel 

public interface IDisplayPersonViewModel 
{ 
    [ScaffoldColumn(false)] 
    public int ID { get; set; } 
} 

public interface IEditPersonViewModel 
{ 
    [Required]     
    [StringLength(20)]     
    public string FirstName { get; set; }     

    [Required]     
    [StringLength(20)]     
    public string LastName { get; set; }     

    [Required]     
    public string Bio { get; set; }     

    [Required]     
    public int ID { get; set; }    
} 

Mẫu người thô của bạn không có thuộc tính. Mô hình Hiển thị và Chỉnh sửa của bạn chỉ có các thuộc tính bạn thực sự cần cho Chế độ xem.

+0

Nhược điểm của điều này là bạn vẫn phải duy trì tất cả các định nghĩa về tài sản – drogon

+0

Đồng ý, nhưng những gì bạn không có là một mô hình ghép với một màn hình cụ thể cũng không xác nhận. Bạn vẫn có thể sử dụng bất kỳ "plugin" xác thực nào và tạo nhiều loại hiển thị mà không cần chạm vào mô hình thô của mình. –

+0

bạn đã làm một công việc tuyệt vời. Tôi đã bị mắc kẹt trong việc tìm kiếm giải pháp cho loại vấn đề này từ 10 ngày qua. Cảm ơn!!!! :) –

Các vấn đề liên quan