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
dan AddEmployeeMailingAddress
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]
public ActionResult Save(IEnumerable<IUserAction<Employee>> actions)
{
var errors = new List<string>();
foreach( var action in actions )
{
var employee = _employeeRepository.Get(action.ModelId);
errors.AddRange(action.Validate(employee));
}
foreach( var action in editModel.UserActions )
{
var employee = _employeeRepository.Get(action.ModelId);
action.Complete(employee);
_employeeRepository.Update(employee);
}
}
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.