Setiap artikel yang ditemukan di Internet tentang penggunaan ViewModels dan penggunaan Automapper memberikan panduan tentang pemetaan arah "Controller -> View". Anda mengambil model domain bersama dengan semua Daftar Pilihan menjadi satu ViewModel khusus dan meneruskannya ke tampilan. Itu jelas dan bagus.
Tampilan memiliki bentuk, dan akhirnya kita berada dalam aksi POST. Di sini semua Pengikat Model datang ke tempat kejadian bersama dengan [jelas] Model Tampilan lain yang [jelas] terkait dengan ViewModel asli setidaknya dalam bagian konvensi penamaan demi pengikatan dan validasi.
Bagaimana Anda memetakannya ke Model Domain Anda?
Biarlah itu tindakan penyisipan, kita bisa menggunakan Automapper yang sama. Tetapi bagaimana jika itu adalah tindakan pembaruan? Kita harus mengambil Entitas Domain kita dari Repositori, memperbarui propertinya sesuai dengan nilai di ViewModel dan menyimpannya ke Repositori.
TAMBAHAN 1 (9 Februari 2010): Terkadang, menetapkan properti Model tidak cukup. Harus ada tindakan yang diambil terhadap Model Domain sesuai dengan nilai Model Tampilan. Yaitu, beberapa metode harus dipanggil pada Model Domain. Mungkin, harus ada semacam lapisan Layanan Aplikasi yang berdiri di antara Pengontrol dan Domain untuk memproses Model Tampilan ...
Bagaimana mengatur kode ini dan di mana menempatkannya untuk mencapai tujuan berikut?
- jaga pengontrol tetap tipis
- menghormati latihan SoC
- ikuti prinsip Desain Berdasarkan Domain
- kering
- bersambung ...
sumber
Alat seperti AutoMapper dapat digunakan untuk memperbarui objek yang ada dengan data dari objek sumber. Tindakan pengontrol untuk memperbarui mungkin terlihat seperti:
[HttpPost] public ActionResult Update(MyViewModel viewModel) { MyDataModel dataModel = this.DataRepository.GetMyData(viewModel.Id); Mapper<MyViewModel, MyDataModel>(viewModel, dataModel); this.Repostitory.SaveMyData(dataModel); return View(viewModel); }
Terlepas dari apa yang terlihat dalam cuplikan di atas:
Tindakan pengontrol cukup tipis dan kekhawatiran dipisahkan: masalah pemetaan ditangani dalam konfigurasi AutoMapper, validasi dilakukan oleh ModelBinder dan akses data oleh Repositori.
sumber
Saya ingin mengatakan bahwa Anda menggunakan kembali istilah ViewModel untuk kedua arah interaksi klien. Jika Anda telah cukup membaca kode ASP.NET MVC di alam liar, Anda mungkin telah melihat perbedaan antara ViewModel dan EditModel. Saya pikir itu penting.
Sebuah ViewModel mewakili semua informasi yang diperlukan untuk merender tampilan. Ini bisa mencakup data yang dirender di tempat non-interaktif statis dan juga data murni untuk melakukan pemeriksaan guna memutuskan apa yang akan dirender. Tindakan GET Pengontrol umumnya bertanggung jawab untuk mengemas ViewModel untuk Tampilannya.
EditModel (atau mungkin ActionModel) mewakili data yang diperlukan untuk melakukan tindakan yang ingin dilakukan pengguna untuk POST tersebut. Jadi EditModel benar-benar mencoba menggambarkan suatu tindakan. Ini mungkin akan mengecualikan beberapa data dari ViewModel dan meskipun terkait, saya pikir penting untuk menyadari bahwa mereka memang berbeda.
Satu Ide
Yang mengatakan Anda dapat dengan mudah memiliki konfigurasi AutoMapper untuk pergi dari Model -> ViewModel dan yang lain untuk pergi dari EditModel -> Model. Kemudian tindakan Controller yang berbeda hanya perlu menggunakan AutoMapper. Sungguh, EditModel dapat memiliki fungsi di atasnya untuk memvalidasi propertinya terhadap model dan menerapkan nilai tersebut ke Model itu sendiri. Itu tidak melakukan hal lain dan Anda memiliki ModelBinders di MVC untuk memetakan Permintaan ke EditModel.
Ide Lain
Di luar itu, sesuatu yang baru-baru ini saya pikirkan seperti itu bekerja dari gagasan ActionModel adalah bahwa apa yang klien posting kembali kepada Anda sebenarnya adalah deskripsi beberapa tindakan yang dilakukan pengguna dan bukan hanya satu gumpalan besar data. Ini tentu akan membutuhkan beberapa Javascript di sisi klien untuk mengelola tetapi menurut saya idenya menarik.
Pada dasarnya saat pengguna melakukan tindakan pada layar yang Anda tunjukkan, Javascript akan mulai membuat daftar objek tindakan. Contohnya adalah mungkin pengguna berada di layar informasi karyawan. Mereka memperbarui nama belakang dan menambahkan alamat baru karena karyawan tersebut baru saja menikah. Di bawah sampul ini menghasilkan sebuah
ChangeEmployeeName
danAddEmployeeMailingAddress
objek ke daftar. Pengguna mengklik 'Simpan' untuk melakukan perubahan dan Anda mengirimkan daftar dua objek, masing-masing hanya berisi informasi yang diperlukan untuk melakukan setiap tindakan.Anda akan membutuhkan ModelBinder yang lebih cerdas daripada yang default tetapi serializer JSON yang baik harus dapat menangani pemetaan objek aksi sisi klien ke sisi server. Yang di sisi server (jika Anda berada dalam lingkungan 2 tingkat) dapat dengan mudah memiliki metode yang menyelesaikan tindakan pada Model tempat mereka bekerja. Jadi tindakan Pengontrol akhirnya hanya mendapatkan Id untuk ditarik contoh Model dan daftar tindakan yang harus dilakukan di atasnya. Atau tindakan memiliki id di dalamnya untuk membuatnya sangat terpisah.
Jadi mungkin sesuatu seperti ini terwujud di sisi server:
public interface IUserAction<TModel> { long ModelId { get; set; } IEnumerable<string> Validate(TModel model); void Complete(TModel model); } [Transaction] //just assuming some sort of 2-tier with transactions handled by filter public ActionResult Save(IEnumerable<IUserAction<Employee>> actions) { var errors = new List<string>(); foreach( var action in actions ) { // relying on ORM's identity map to prevent multiple database hits var employee = _employeeRepository.Get(action.ModelId); errors.AddRange(action.Validate(employee)); } // handle error cases possibly rendering view with them foreach( var action in editModel.UserActions ) { var employee = _employeeRepository.Get(action.ModelId); action.Complete(employee); // against relying on ORMs ability to properly generate SQL and batch changes _employeeRepository.Update(employee); } // render the success view }
Itu benar-benar membuat tindakan posting kembali cukup umum karena Anda mengandalkan ModelBinder untuk memberi Anda instance IUserAction yang benar dan instance IUserAction Anda untuk melakukan logika yang benar itu sendiri atau (lebih mungkin) memanggil Model dengan info tersebut.
Jika Anda berada dalam lingkungan 3 tingkat, IUserAction dapat dibuat menjadi DTO sederhana untuk ditembakkan melintasi batas dan dilakukan dengan metode serupa pada lapisan aplikasi. Bergantung pada bagaimana Anda melakukan lapisan itu, lapisan itu dapat dipecah dengan sangat mudah dan masih tetap dalam transaksi (yang terlintas di benak adalah permintaan / tanggapan Agatha dan memanfaatkan peta identitas DI dan NHibernate).
Bagaimanapun saya yakin itu bukan ide yang sempurna, itu akan membutuhkan beberapa JS di sisi klien untuk mengelola, dan saya belum dapat melakukan proyek untuk melihat bagaimana itu terungkap, tetapi posting mencoba untuk memikirkan bagaimana caranya sampai di sana dan kembali lagi jadi saya pikir saya akan memberikan pikiran saya. Saya harap ini membantu dan saya akan senang mendengar cara lain untuk mengelola interaksi.
sumber
Anda tidak perlu memetakan viewmodel ke domain karena viewmodel Anda mungkin dibuat lebih dari model domain. Model tampilan dioptimalkan untuk layar (ui) dan berbeda dari model domain.
http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/
sumber