2012-04-20 15 views
7

Obecnie używam ViewModels, aby oddzielić moje widoki od rzeczywistej struktury modelu.Model "Połącz" i ViewModel z lub bez AutoMappera?

Na przykład mam jednostkę trwałości użytkownika i MyProfile ViewModel zawierający wszystkie informacje, które użytkownik może zmienić na własną rękę. Do konwersji z użytkownika na MyProfile używam Automapper.

Teraz, gdy użytkownik odsyła swoje (zmienione) informacje, muszę je zapisać. Jednak informacje zawarte w ViewModelu nie są kompletne, a gdy AutoMapper tworzy obiekt trwałości użytkownika z ViewModel, ważne informacje zostaną utracone.

Nie chcę ujawniać tych informacji w widoku warstwy, szczególnie w przypadku ukrytych elementów formularza.

Potrzebuję więc sposobu na połączenie ViewModel w jednostkę trwałości. Czy mogę to zrobić z AutoMapper, czy muszę to zrobić ręcznie?

Przykład:

Moja klasa użytkownika zawiera identyfikator, imię, nazwisko, login i hasło. Użytkownik powinien edytować tylko swoje imię i nazwisko w swoim profilu. Dlatego mój ProfileViewModel zawiera ID, imię i nazwisko. Po przesłaniu informacji z formularza, Automapper tworzy obiekt użytkownika z przesłanego profilu ProfileViewModel, a w tym obiekcie ustawiane są tylko ID, Imię i Nazwisko. Podczas podawania tego elementu do mojego repozytorium utraciłem nazwę użytkownika i hasło.

+0

Dlaczego informacja ta nie jest kompletna? Czy możesz napisać kawałek kodu? –

+0

Użyłem Mapper.Map (model) zamiast najpierw wyszukać użytkownika, a następnie użyć Mapper.Map (użytkownik, model) – ckonig

Odpowiedz

12

Potrzebuję więc sposobu na połączenie ViewModel w jednostkę trwałości. Czy mogę zrobić to za pomocą AutoMapera, czy muszę to zrobić ręcznie?

Tak, możesz to zrobić za pomocą AutoMappera. Na przykład:

public class Model 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class ViewModel 
{ 
    public string Name { get; set; } 
} 

class Program 
{ 
    static void Main() 
    { 
     // define a map (ideally once per appdomain => usually goes in Application_Start) 
     Mapper.CreateMap<ViewModel, Model>(); 

     // fetch an entity from a db or something 
     var model = new Model 
     { 
      Id = 5, 
      Name = "foo" 
     }; 

     // we get that from the view. It contains only a subset of the 
     // entity properties 
     var viewModel = new ViewModel 
     { 
      Name = "bar" 
     }; 

     // Now we merge the view model properties into the model 
     Mapper.Map(viewModel, model); 

     // at this stage the model.Id stays unchanged because 
     // there's no Id property in the view model 
     Console.WriteLine(model.Id); 

     // and the name has been overwritten 
     Console.WriteLine(model.Name); 
    } 
} 

nadrukami:

5 
bar 

i przełożenia tego na typową ASP.NET MVC wzór:

[HttpPost] 
public ActionResult Update(MyViewModel viewModel) 
{ 
    if (!ModelState.IsValid) 
    { 
     // validation failed => redisplay view 
     return View(viewModel); 
    } 

    // fetch the domain entity that we want to udpate 
    DomainModel model = _repository.Get(viewModel.Id); 

    // now merge the properties 
    Mapper.Map(viewModel, model); 

    // update the domain model 
    _repository.Update(mdoel); 

    return RedirectToAction("Success"); 
} 
+0

Dobra, teraz ma to sens! Wygląda znacznie lepiej niż przy użyciu metody Blackboxed UpdateModel(). – ckonig