2012-03-04 27 views
5

Yeni bir nesne oluştururken, bir viewmodel kullanmanın en iyi yolunu bulmaya çalışıyorum.ASP.NET MVC 3 Viewmodel Pattern

Bir iletişim nesnesini ve şirketlerin belirli bir listesini içeren çok basit bir görünüm modelim var.

private ICompanyService _Service; 
public SelectList ContactCompanyList { get; private set; } 
public Contact contact { get; private set; } 

public ContactCompanyViewModel(Contact _Contact) 
{ 
    _Service = new CompanyService(); 
    contact = _Contact; 
    ContactCompanyList = GetCompanyList(); 
} 

private SelectList GetCompanyList() 
{ 
    IEnumerable<Company> _CompanyList = _Service.GetAll(); 
    return new SelectList(_CompanyList, "id", "name");  
} 

Daha sonra bu viewmodel'i kullanan ve kişim için ilişkili bir şirket seçmeme izin veren kişi denetleyicim var.

[Authorize] 
public ActionResult Create() 
{      
    return View(new ContactCompanyViewModel(new Contact())); 
} 

Sorunum denetleyicideki oluşturma yöntemidir.

[Authorize] 
[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create(Contact _Contact) 
{ 
    try 
    { 
     _Service.Save(_Contact); 
     return RedirectToAction("Index"); 
    } 
    catch 
    { 
     return View(); 
    } 
} 

Sorun, görünümün boş bir kişi nesnesi döndürmesidir, ancak! Şirket kimliği doldurulur, bunun nedeni açılır listenin alan adını açıkça beyan etmesidir. HTML.EditorFor yardımcı kullanırken

@Html.DropDownList("parent_company_id",Model.ContactCompanyList) 

standart html form alanları benim yaratmak eylem olarak bir FormCollection kullanırsanız

@Html.EditorFor(model => model.contact.forename) 

ben erişebilirsiniz ... contact.forename biçiminde geri nesneleri değerler iletin yöntem paremeter ve sonra contact.value için açık bir şekilde arama ancak kodumu güzel ve temiz tutmak ve her seferinde yeni bir iletişim nesnesi oluşturmak zorunda kalmamak için bir İletişim nesnesi parametre olarak kullanamıyorum.

Gerçek görünüm modeli nesnesini bir parametre olarak geri almayı denedim, ancak bu yalnızca bir yapıcı hatasıyla yanıp söner (Bu görünüm, görünüm nesnesine iletişim nesnesine değil, görünüm modeline bağlıyken kafa karıştırıcıdır).

Html.EditFor alanının adını tanımlayabilmem için bir yol var mı? Böylece, denetleyicide, oluşturma eylemi yöntemine geri döndüğünde değer ilgili nesneye doğru yeniden eşlensin mi? Ya da bir yerde bir FUBAR hatası yaptım (bu bir öğrenme alıştırması olduğu için en olası açıklamadır!).

cevap

15

Görünüm modeliniz yanlış görünüyor. Görünüm modelleri herhangi bir hizmete başvurmamalıdır. Görünüm modelleri herhangi bir alan modeli referans olmamalıdır. Görünüm modelleri parametresiz yapıcılara sahip olmalı, böylece POST işlem parametreleri olarak kullanılabilirler. Yani burada

senaryonuz için daha gerçekçi bir görünüm modeli:

public class ContactCompanyViewModel 
{ 
    public string SelectedCompanyId { get; set; } 
    public IEnumerable<SelectListItem> CompanyList { get; set; } 

    ... other properties that the view requires 
} 

ve sonra hazırlamak ve bu görünüm modelini dolduracaktır GET eylemi olabilir:

public ActionResult Create() 
{ 
    var model = new ContactCompanyViewModel(); 
    model.CompanyList = _Service.GetAll().ToList().Select(x => new SelectListItem 
    { 
     Value = x.id.ToString(), 
     Text = x.name 
    }); 
    return View(model); 
} 

ve POST eylemi :

ve şimdi görünümünüzde, görünüm modelinizle çalışırsınız:

@model ContactCompanyViewModel 
@using (Html.BeginForm()) 
{ 
    @Html.DropDownListFor(x => x.SelectedCompanyId, Model.CompanyList) 

    ... other input fields for other properties 

    <button type="submit">Create</button> 
} 
+0

Bu sorun, viewmodel'i oluşturma eylemi yöntemiyle eşleştirmemi sağlayarak sorunu çözdü, o zamana kadar olan tek sorun, açılan değerin bağlı olmamasıydı, açılan adı değiştirerek bunu çözdüm ** @ Html.DropDownList ("contact.parent_company_id", Model.ContactCompanyList).** Tek sorum, neden manuel olarak haritalandığınız hakkında mı? Popüle edilmiş bir iletişim nesnesini içeren modele sahipsin, haritalanacak hiç bir şey yok mu? –

+1

@DavidAbraham, süreci göstermek için elle eşleştirdim. Gerçek bir uygulamada bu işi yapmak için AutoMapper: http://automapper.org/ kullanıyorum. –

+0

Ama yine de Automapper'a gerek yok, benim durumumda, şimdi tam olarak doldurulmuş bir iletişim alanı nesnesini içeren bir viewmodel nesnesini geçmiştim, haritalanacak hiçbir şey yok - otomatik mapper nereden geliyor? –