2009-08-18 21 views
23

Hiện tại tôi đang chuyển các đối tượng miền của mình đến các chế độ xem của mình và liên kết trực tiếp với chúng từ các POST. Mọi người đều nói điều này là xấu, vì vậy tôi đang cố gắng thêm vào khái niệm ViewModel.bằng cách sử dụng ViewModels cho các hành động POST trong MVC thanh lịch

Tuy nhiên, tôi không thể tìm cách để làm điều này rất thanh lịch, và tôi muốn biết những giải pháp của người khác là không kết thúc với một hành động điều khiển rất lộn xộn.

quá trình tiêu biểu cho tiếng nói một số "thêm người" chức năng trông như thế này:

  1. tạo ra một yêu cầu GET cho một cái nhìn đại diện cho một viewmodel Person trống
  2. bài trở lại (in) dữ liệu hợp lệ
  3. bộ điều khiển liên kết dữ liệu được đăng lên một chế độ xem người
  4. nếu ràng buộc không thành công, tôi cần thực hiện hành động tương tự như trong (1) nhưng với một số dữ liệu, không phải đối tượng trống và lỗi
  5. nếu ràng buộc thành công, tôi cần để ánh xạ các thuộc tính từ VM lên một mô hình thực
  6. xác nhận mô hình
  7. nếu xác nhận thông qua: tiết kiệm người đó, cam kết, bản đồ chi tiết người dùng một màn hình máy ảo và gửi lại trong một cái nhìn
  8. nếu xác nhận không thành công, thực hiện các thao tác tương tự như trong (1) nhưng với một số dữ liệu và lỗi

Làm tất cả điều này trong hành động điều khiển (bỏ qua GET) chắc chắn không phải là SRP hoặc DRY.

Tôi đang cố gắng nghĩ ra cách phá vỡ quy trình này để nó tuân thủ SRP, sạch sẽ, mô-đun và trên tất cả có thể kiểm chứng.

Giải pháp cho mọi người là gì?

Tôi đã thử nghiệm với người điều khiển hành động tùy chỉnh để tách mối quan tâm thành các phương pháp riêng lẻ, modelbinders thông minh và chỉ là lực lượng vũ phu đơn thuần nhưng tôi chưa tìm thấy giải pháp hài lòng.

P.S. khi nó thêm vào rất nhiều sự phức tạp, hãy thuyết phục tôi tại sao tôi thậm chí cần phải bận tâm

+0

Bạn đã làm gì? –

+1

không có gì được nêu ra: (vẫn cố gắng để quyết định một giải pháp thanh lịch để bộ điều khiển của tôi không kết thúc thực sự lộn xộn.Tôi nghĩ rằng câu trả lời thực sự là openrasta –

+0

Có lẽ những bài viết này có thể giúp một chút: http://stackoverflow.com/a/25460769/3969501, http://stackoverflow.com/a/25169023/1475331 –

Trả lời

2

Mô hình MVVM (ViewModel) chắc chắn là thứ cần thực hiện, tôi có câu hỏi tương tự về việc gửi lại một hành động vài ngày trở lại - tại đây là liên kết: MVVM and ModelBinders in the ASP.NET MVC Framework

Kết quả là bạn có thể sử dụng thuộc tính Bind để đăng lại loại phức tạp mà bạn muốn.

6

Tôi cảm thấy khó chịu tương tự. Cách duy nhất của tôi xung quanh nó đã được thực hiện như sau:

  1. Tạo một chất kết dính để ràng buộc và kích hoạt các mô hình xem
  2. Tạo một chất kết dính để có được những thực thể từ cơ sở dữ liệu (hoặc chỉ cần làm điều này trong bộ điều khiển)
  3. Gọi phương thức Lưu kế thừa trong siêu lớp. Phương thức này lấy viewmodel và thực thể sẽ được cập nhật và thực hiện tất cả công việc bạn đã liệt kê trong các bước của mình.

Phương pháp hành động trông như thế này:

public ActionResult Whatever(TViewModel viewModel, TEntity entity) 
{ 
    return Save(viewModel, entity); 
} 

Bộ điều khiển cơ sở có một định nghĩa chung chung, như vậy:

public abstract BaseController<TEntity, TViewModel> 
    where TEntity : Entity 
    where TViewModel : ViewModel 

Các nhà xây dựng có hai phụ thuộc, một cho kho thực thể và người khác cho người lập bản đồ mô hình, như vậy:

protected BaseController(IRepository<TEntity> repository, IMapper<TEntity, TViewModel> mapper) 

Với điều này tại chỗ, sau đó bạn có thể viết một phương thức Save bảo vệ có thể được gọi từ những hành động điều khiển trong lớp con, như vậy:

protected ActionResult Save(TViewModel viewModel, TEntity entity) 
{ 
    if (!ModelState.IsValid) 
     return View(viewModel); 

    _mapper.Map(viewModel, entity); 
    if (!entity.IsValid) 
    { 
     // add errors to model state 
     return View(viewModel); 
    } 

    try 
    { 
     _repository.Save(entity); 
     // either redirect with static url or add virtual method for defining redirect in subclass. 
    } 
    catch (Exception) 
    { 
     // do something here with the exception 
     return View(viewModel); 
    } 
} 

As far as testability, bạn có thể kiểm tra các phương pháp tiết kiệm đi qua trong hợp lệ/các mô hình và thực thể xem không hợp lệ. Bạn có thể kiểm tra việc thực hiện trình ánh xạ mô hình, trạng thái hợp lệ của mô hình khung nhìn và trạng thái hợp lệ của thực thể một cách riêng biệt.

Bằng cách tạo bộ điều khiển cơ sở chung, bạn có thể lặp lại mẫu này cho từng tổ hợp/tổ hợp khung nhìn trong miền của bạn, nếu bạn đang tạo nhiều bộ điều khiển để thực hiện tương tự.

Tôi rất muốn nghe những gì người khác nói về điều này. Câu hỏi tuyệt vời.

+0

ý tưởng thú vị +1 –

+2

Ý tưởng chắc chắn thú vị, nhưng OpenRASTA vẫn là một lựa chọn tốt hơn :) – Dve

0

tôi có nhiều giải pháp tốt trong asp.net ứng dụng mẫu MVC mà là trong download of valueinjecter (mapper mà tôi sử dụng để lập bản đồ ViewModels đến/từ các thực thể, bạn cũng có thể lập bản đồ FormCollection/Request to Entities)

đây là một:

public class TinyController :Controller 
     { 
      private readonly IModelBuilder<Person, PersonViewModel> modelBuilder; 

      public TinyController() 
      { 
       modelBuilder = new PersonModelBuilder(); 
      } 

      public ActionResult Index() 
      { 
       return View(modelBuilder.BuildModel(new PersonRepository().Get())); 
      } 

      [HttpPost] 
      public ActionResult Index(PersonViewModel model) 
      { 
       if (!ModelState.IsValid) 
        return View(modelBuilder.RebuildModel(model)); 

        var entity = modelBuilder.BuildEntity(model); 
... 
//save it or whatever 
      } 
     } 
Các vấn đề liên quan