2012-03-04 14 views
5

मैं एक नई वस्तु बनाने के मामले में एक व्यूमोडेल का उपयोग करने का सबसे अच्छा तरीका काम करने की कोशिश कर रहा हूं।एएसपी.नेट एमवीसी 3 व्यूमोडेल पैटर्न

मेरे पास एक बहुत ही सरल दृश्य मॉडल है जिसमें एक संपर्क वस्तु और कंपनियों की एक चुनी सूची शामिल है।

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");  
} 

मेरे पास संपर्क नियंत्रक है जो इस व्यूमोडेल का उपयोग करता है और मुझे अपने संपर्क के लिए संबंधित कंपनी का चयन करने में सक्षम बनाता है।

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

मेरा मुद्दा नियंत्रक पर निर्माण विधि के साथ है।

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

समस्या यह है कि दृश्य एक खाली संपर्क वस्तु देता है, लेकिन! कंपनी आईडी आबादी है, ऐसा इसलिए है क्योंकि ड्रॉपडाउन सूची स्पष्ट रूप से इसके फ़ील्ड नाम की घोषणा करती है।

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

मानक एचटीएमएल प्रपत्र फ़ील्ड्स जब HTML.EditorFor सहायक का उपयोग कर contact.forename के प्रारूप में वापस वस्तुओं मान पास ...

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

यदि मैं अपना बनाने कार्रवाई के रूप में एक FormCollection का उपयोग मैं उन तक पहुँच सकते विधि पैरामीटर और फिर स्पष्ट रूप से contact.value के लिए खोजें लेकिन मैं अपने कोड को अच्छे और साफ रखने के लिए एक पैरामीटर के रूप में एक संपर्क ऑब्जेक्ट का उपयोग नहीं कर सकता और हर बार एक नया संपर्क ऑब्जेक्ट नहीं बनाना चाहता।

मैंने वास्तविक दृश्य मॉडल ऑब्जेक्ट को पैरामीटर के रूप में वापस करने का प्रयास किया लेकिन यह केवल एक कन्स्ट्रक्टर त्रुटि के साथ उड़ाता है (जो देखने में भ्रमित है क्योंकि दृश्य दृश्य मॉडल से संपर्क है, संपर्क वस्तु नहीं है)।

क्या कोई तरीका है कि मैं Html.EditFor फ़ील्ड का नाम परिभाषित कर सकता हूं ताकि मेरे नियंत्रक पर क्रिया क्रिया विधि पर वापस जाने पर मूल्य मानचित्र सही ढंग से संपर्क ऑब्जेक्ट पर वापस आ सकें? या मैंने कहीं कुछ फ़बर गलती की है (यह सबसे संभावित स्पष्टीकरण है क्योंकि यह एक सीखने का अभ्यास है!)।

उत्तर

15

आपका दृश्य मॉडल गलत लगता है। मॉडल देखें किसी भी सेवाओं का संदर्भ नहीं देना चाहिए। मॉडल देखें किसी भी डोमेन मॉडल का संदर्भ नहीं देना चाहिए। मॉडल देखें पैरामीटर रहित कन्स्ट्रक्टर होना चाहिए ताकि उन्हें POST एक्शन पैरामीटर के रूप में उपयोग किया जा सके।

तो यहाँ

अपने परिदृश्य के लिए और वास्तविक दृश्य मॉडल है:

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

    ... other properties that the view requires 
} 

और फिर आप एक प्राप्त कार्रवाई है कि तैयार करने और इस दृश्य मॉडल से स्थापित हो जाएगा हो सकता है:

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); 
} 

और एक पोस्ट कार्रवाई :

[HttpPost] 
public ActionResult Create(ContactCompanyViewModel model) 
{ 
    try 
    { 
     // TODO: to avoid this manual mapping you could use a mapper tool 
     // such as AutoMapper 
     var contact = new Contact 
     { 
      ... map the contact domain model properties from the view model 
     }; 
     _Service.Save(contact); 
     return RedirectToAction("Index"); 
    } 
    catch 
    { 
     model.CompanyList = _Service.GetAll().ToList().Select(x => new SelectListItem 
     { 
      Value = x.id.ToString(), 
      Text = x.name 
     }); 
     return View(model); 
    } 
} 

और अब आपके विचार में आप अपने दृश्य मॉडल के साथ काम करते हैं:

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

    ... other input fields for other properties 

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

धन्यवाद, जिसने मुझे दृश्य कार्रवाई विधि में व्यूमोडेल को मैप करने के लिए सक्षम करके समस्या का समाधान किया, तब एकमात्र मुद्दा था कि ड्रॉप डाउन वैल्यू बाध्य नहीं था, मैंने इसे ड्रॉप डाउन नाम बदलकर हल किया ** @ एचटीएमएल.ड्रॉपडाउनलिस्ट ("contact.parent_company_id", मॉडल। संपर्क कॉम्पैनीलिस्ट)।** मेरा एकमात्र सवाल यह है कि आप मैन्युअल रूप से मानचित्रण क्यों कर रहे हैं? आपके पास एक मॉडल है जिसमें एक जनसंख्या संपर्क वस्तु है, मानचित्र करने के लिए कुछ भी नहीं है? –

+1

@ डेविड अब्राहम, मैंने प्रक्रिया को चित्रित करने के लिए मैन्युअल रूप से मैप किया। एक वास्तविक एप्लिकेशन में मैं ऑटोमैपर का उपयोग करता हूं: http://automapper.org/ यह काम करने के लिए। –

+0

लेकिन फिर भी ऑटोमैपर के लिए कोई ज़रूरत नहीं है, मेरे मामले में मैंने अब एक व्यूमोडेल ऑब्जेक्ट को पास कर दिया है जिसमें एक संपर्क डोमेन ऑब्जेक्ट है जो अब पूरी तरह से पॉप्युलेट हो गया है, मानचित्र के लिए कुछ भी नहीं है - ऑटो मैपर इसमें कहां आता है? –

संबंधित मुद्दे