Müşteri etkileşiminin her iki yönü için ViewModel terimini yeniden kullandığınızı söylemek isterim. Vahşi ortamda yeterince ASP.NET MVC kodu okuduysanız, muhtemelen bir ViewModel ve bir EditModel arasındaki farkı görmüşsünüzdür. Bunun önemli olduğunu düşünüyorum.
Bir ViewModel, bir görünümü oluşturmak için gereken tüm bilgileri temsil eder. Bu, etkileşimli olmayan statik yerlerde oluşturulan verileri ve ayrıca yalnızca tam olarak neyin oluşturulacağına karar vermek için bir kontrol gerçekleştirmek için verileri içerebilir. Bir Denetleyici GET eylemi genellikle ViewModel'in Görünümü için paketlenmesinden sorumludur.
Bir EditModel (veya belki bir ActionModel), kullanıcının o POST için yapmak istediği eylemi gerçekleştirmek için gereken verileri temsil eder. Yani bir EditModel gerçekten bir eylemi tanımlamaya çalışıyor. Bu muhtemelen bazı verileri ViewModel'den hariç tutacaktır ve ilgili olmasına rağmen bunların gerçekten farklı olduklarını anlamanın önemli olduğunu düşünüyorum.
Bir Fikir
Bu, Model -> ViewModel'den gitmek için bir AutoMapper yapılandırmasına ve EditModel -> Model'e gitmek için farklı bir yapılandırmaya kolayca sahip olabileceğinizi söyledi. O zaman farklı Denetleyici eylemlerinin yalnızca AutoMapper'ı kullanması gerekir. Cehennem EditModel, modele karşı özelliklerini doğrulamak ve bu değerleri Modelin kendisine uygulamak için üzerinde işlevlere sahip olabilir. Başka bir şey yapmıyor ve yine de Talebi EditModel ile eşlemek için MVC'de ModelBinders var.
Diğer bir fikir
Bunun ötesinde, son zamanlarda bir ActionModel fikrinden yola çıkarak düşündüğüm bir şey de, müşterinin size geri gönderdiği şeyin aslında kullanıcının gerçekleştirdiği birkaç eylemin açıklaması ve yalnızca bir veri yığını değil. Bu kesinlikle istemci tarafında yönetmek için biraz Javascript gerektirecektir, ancak fikir bence ilgi çekici.
Esasen, kullanıcı sunduğunuz ekranda eylemler gerçekleştirirken, Javascript bir eylem nesneleri listesi oluşturmaya başlayacaktır. Bir örnek, muhtemelen kullanıcı bir çalışan bilgi ekranındadır. Çalışan yakın zamanda evlendiği için soyadını günceller ve yeni bir adres eklerler. Kapakların altında bu, bir listeye bir ChangeEmployeeName
ve bir AddEmployeeMailingAddress
nesne oluşturur. Kullanıcı değişiklikleri uygulamak için 'Kaydet'i tıklar ve her biri yalnızca her eylemi gerçekleştirmek için gereken bilgileri içeren iki nesnenin listesini gönderirsiniz.
Daha akıllı bir ModelBinder'e ihtiyacınız olacaktır, bu durumda varsayılan olanı ancak iyi JSON serileştiricisi, istemci tarafı eylem nesnelerinin sunucu tarafındaki nesnelerle eşleştirilmesini sağlayabilmelidir. Sunucu tarafı olanlar (2 katmanlı bir ortamdaysanız), birlikte çalıştıkları Model üzerindeki eylemi tamamlayan yöntemlere kolayca sahip olabilir. Dolayısıyla, Denetleyici eylemi, yalnızca Model örneğinin çekmesi için bir Kimlik ve üzerinde gerçekleştirilecek eylemlerin bir listesini alır. Veya eylemlerin içinde onları çok ayrı tutacak bir kimlik vardır.
Yani belki sunucu tarafında bunun gibi bir şey gerçekleşebilir:
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);
}
}
Bu, geri gönderme eylemini gerçekten oldukça genel kılar, çünkü size doğru IUserAction örneğini ve IUserAction örneğinizi doğru mantığı gerçekleştirmek veya (daha büyük olasılıkla) bilgi ile Modele çağrı yapmak için size güveniyorsunuz.
Eğer 3 katmanlı bir ortamda olsaydınız, IUserAction sadece basit DTO'lar haline getirilebilir ve sınırın ötesinde çekilebilir ve uygulama katmanında benzer bir yöntemle gerçekleştirilebilir. Bu katmanı nasıl yaptığınıza bağlı olarak, çok kolay bir şekilde bölünebilir ve yine de bir işlemde kalabilir (akla gelen, Agatha'nın isteği / yanıtı ve DI ve NHibernate'in kimlik haritasından yararlanılmasıdır).
Her neyse, bunun mükemmel bir fikir olmadığından eminim, müşteri tarafında yönetmek için biraz JS gerektirecekti ve nasıl gelişeceğini görmek için henüz bir proje yapamadım, ancak gönderi nasıl yapılacağını düşünmeye çalışıyordu oraya git ve tekrar geri dön, böylece düşüncelerimi vereceğimi düşündüm. Umarım yardımcı olur ve etkileşimleri yönetmenin başka yollarını duymak isterim.