2009-07-17 15 views
7

मैंने लेख, किताबें और उदाहरणों में कार्यों को बनाने के कई उदाहरण देखे हैं। ऐसा लगता है कि दो प्रचलित शैलियों हैं।जो अधिक सही है: UpdateModel() का उपयोग करके या पैरामीटर के रूप में मॉडल प्राप्त करना?

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create(FormCollection collection) 
{ 
    try 
    { 
     var contact = Contact.Create(); 
     UpdateModel<Contact>(contact); 
     contact.Save(); 
     return RedirectToAction("Index"); 
    } 
    catch (InvalidOperationException ex) 
    { 
     return View(); 
    } 
} 

और ...

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create([Bind(Exclude="Id")]Contact contact) 
{ 
    try 
    { 
     contact.Save(); // ... assumes model does validation 
     return RedirectToAction("Index"); 
    } 
    catch (Exception ex) 
    { 
     // ... have to handle model exceptions and populate ModelState errors 
     // ... either here or in the model's validation 
     return View(); 
    } 
} 

मैं दोनों तरीकों की कोशिश की है और दोनों pluses और minuses है, IMO।

उदाहरण के लिए, फॉर्मकोलेक्शन संस्करण का उपयोग करते समय मुझे अपने मॉडल बाइंडर में मैन्युअल रूप से "आईडी" से निपटना होगा क्योंकि बाइंड/बहिष्कार यहां काम नहीं करता है। विधि के टाइप किए गए संस्करण के साथ मैं मॉडल बाइंडर का उपयोग नहीं करता हूं। मुझे मॉडल बाइंडर का उपयोग करना पसंद है क्योंकि यह मुझे मॉडलस्टेट त्रुटियों को मेरे मॉडल के सत्यापन कोड में मॉडलस्टेट के बारे में जानकारी के बिना पॉप्युलेट करने देता है।

कोई अंतर्दृष्टि?

अद्यतन: मैं अपने ही सवाल का जवाब है, लेकिन मैं अभ्यस्त में चिह्नित जैसा भी मामला किसी में कुछ दिनों के लिए दिए एक बेहतर जवाब है।

उत्तर

2

ठीक है, कुछ डूबने के बाद मुझे पता चला कि क्या स्पष्ट होना चाहिए: मॉडल को पास करना क्योंकि पैरामीटर केवल दृश्य मॉडल के पीछे उपयोग करने के लिए डिफ़ॉल्ट मॉडल बाइंडर का कारण बनता है। चूंकि यह मेरा सबसे बड़ा कारण था कि दृढ़ता से टाइप किए गए संस्करण का उपयोग न करें, तो मुझे लगता है कि अब ऐसा कोई कारण नहीं है।

इसके अलावा, मेरे कोड इस तरह दिखना चाहिए:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create([Bind(Exclude="Id")]Contact contact) 
{ 
    if(!ModelState.IsValid) 
     return View(); 

    contact.Save(); 
    return RedirectToAction("Index"); 
} 
+0

समस्या आप तथापि FormCollection का उपयोग नहीं कर पाएंगे, प्रतिबंध है:

यहां तक ​​कि इस मामले में जहां आप एक मौजूदा इकाई मॉडल अपडेट करना चाहते हैं, आप अब भी इस पैटर्न एक दृश्य मॉडल शुरू करने से उपयोग करना चाहिए। आपके पास बाध्य होने पर जुर्माना नियंत्रण नहीं है। इस पोस्ट पर मेरी पोस्ट देखें http://goneale.com/2009/07/27/updating-multiple-child-objects-and-or-collections-in-asp-net-mvc-views/ – GONeale

0

कोई सही या गलत शैलियां हैं। यदि DefaultModelBinder आपकी आवश्यकताओं के अनुरूप है - हमेशा दृढ़ता से टाइप किए गए संस्करण का उपयोग करें। यदि आप DefaultModelBinder का उपयोग नहीं कर सकते हैं - कस्टम मॉडलबिंडर बनाने या FormCollection एक्शन पैरामीटर का उपयोग करने के बीच चुनें।

3

उपयोग UpdateModel जब आप एक पहले से ही मौजूद मॉडल वस्तु है, जो आप डेटाबेस से प्राप्त कर सकते हैं अद्यतन करने के लिए चाहते हैं या आप कुछ विशिष्ट तरीके से मॉडल वस्तु का दृष्टांत करना चाहते

जैसे:

[AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult EditEmployee(int id, FormCollection collection) 
    { 

try 
    { 

    Contact contact = repository.getContact(id); 
    UpdateModel(contact, collection.ToValueProvider()); 
    repository.save(); 
    return RedirectToAction("Index"); 

} 

    catch 
    { 
    //Handle 
    return View(); 
    } 

} 

आप तो उपर्युक्त आवश्यकताएं नहीं हैं तो इसे क्रिया पैरामीटर के रूप में रखें।

1

आपको हमेशा मॉडल को एक्शन पैरामीटर के रूप में स्वीकार करना चाहिए, क्योंकि यह विधि टेस्टेबल बनाता है।

यह दूर आपके यूनिट परीक्षण से मॉडल ऑब्जेक्ट में पास करना आसान है, ताकि पूरे HttpContext को मैक करने के लिए अद्यतन मॉडेल द्वारा उठाए जाने वाले डेटा प्रदान किए जा सकें।

[HttpPost] 
public ActionResult Edit(int id, EditContactViewModel viewModel) 
{ 
    if (ModelState.IsValid) 
    { 
     Contact contact = _db.GetContact(id) 

     contact.Name = viewModel.Name; 

     _db.SaveChanges(); 

     return RedirectToAction("Index"); 
    } 

    return View(viewModel); 
} 
संबंधित मुद्दे