2011-12-22 9 views
8

आम आदमी के शब्दों में, UpdateModel() क्या करता है, साथ ही साथ TryUpdateModel()? मुझे लगता है कि (एसओ या वेब पर) वास्तव में क्या करता है (स्पष्ट शब्दों में), किसी भी व्यक्ति को इसका उपयोग करने में समस्याएं हैं, इस बारे में कोई स्पष्ट स्पष्टीकरण नहीं मिल रहा है।UpdateModel() क्या करता है?

विजुअलस्टूडियो का इंटेलिजेंस मेरी मदद नहीं कर रहा है। कारण है कि मैं पूछना है, क्योंकि, चलो कहते हैं, अगर मैं अपने नियंत्रक में इस है:

[HttpPost] 
public ActionResult Index(UserViewModel vm, FormCollection form) 
{  
    var statesCheckBoxes = form["StatesList"];  

    vm.BA.StatesTraveledTo = statesCheckBoxes.Split(',').ToList<string>(); 

    return View(vm); 
} 

मैं पहले से ही vm.BA.StatesTraveledTo की स्थापना करके अपने मॉडल को अद्यतन करने के लिए नहीं कर रहे हैं? मुझे अपडेटमोडेल चलाने की आवश्यकता क्यों है? इसके अलावा, जब मैं वास्तव में करने की कोशिश निम्नलिखित:

[HttpPost] 
public ActionResult Index(UserViewModel vm, FormCollection form) 
{  
    var statesCheckBoxes = form["StatesList"];  

    vm.BA.StatesTraveledTo = statesCheckBoxes.Split(',').ToList<string>(); 

    UpdateModel(vm); // IS THIS REDUNDANT TO THE PREVIOUS LINE? 

    return View(vm); 
} 

कुछ भी नहीं है कि में होना है जब मैं ModelState का मूल्य का निरीक्षण (के बाद मैं UpdateModel() चलाने), मैं कुछ भी नहीं दिख रहा है कि कुछ भी यह दर्शाता है लगता है बदल गया है। मुझे मॉडलस्टेट शब्दकोश में एक नई कुंजी नहीं दिखाई दे रही है।

वास्तव में उलझन में। धन्यवाद!

संपादित करें:

पोस्ट करना ViewModel और मॉडल कक्षाओं के लिए स्रोत कोड:

public class UserViewModel 
{ 
    public BankAccount BA { get; set; } 
} 

public class BankAccount 
{ 
    public Person User { get; set; } 
    public List<string> StatesTraveledTo { get; set; } 
} 

public class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public int Age { get; set; } 
} 
+1

यहाँ यह के लिए स्रोत कोड है: http://aspnet.codeplex.com/SourceControl/changeset/view/72551#266451 यह बहुत सरल ,, बस एक ModelBindingContext बनाता है और यह भी बांधता –

+1

है, यह कुछ हद तक है दृश्य में एक क्रिया में इनपुट के रूप में प्राप्त होने वाली वही वस्तु को पार करने के लिए दुर्लभ, ऐसा होता है लेकिन यह दुर्लभ है और यह उन उपयोगों में से एक जैसा प्रतीत नहीं होता है। आम तौर पर आप एक ऑब्जेक्ट इनपुट के रूप में लेते हैं जो पोस्ट किए गए डेटा का प्रतिनिधित्व करता है और फिर –

+0

दृश्य के लिए एक अलग मॉडल बनाएं। मॉडल को वापस देखने के कारण मैं सत्यापन उद्देश्यों के लिए है। इसलिए यदि सत्यापन विफल रहता है, तो मैं चाहता हूं कि मॉडल और उसके मान दृश्य में पारित किए जाएं ताकि फ़ॉर्म फ़ील्ड को दोबारा तैयार किया जा सके और एक त्रुटि संदेश दिखाया गया हो। क्षमा करें, मुझे लगता है कि मैंने दिखाए गए कोड के साथ, यह एक व्यावहारिक उदाहरण की तरह नहीं लग सकता है। – SaltProgrammer

उत्तर

5

क्या होता है जब आप

public ActionResult Index(UserViewModel vm) 
{ } 

लिख सकते हैं और जब आप ActionResult में निरीक्षण आप पाते हैं कि vm मूल्यों जिन्हें आप दृश्य से तैनात हैं। ऐसा इसलिए है क्योंकि एमवीसी विभिन्न स्रोतों (फॉर्म संग्रह, मार्ग मान, क्वेरीस्ट्रिंग इत्यादि) से मूल्य निकालने के लिए मॉडलबिंडर को निर्देशित करता है और आपके मॉडल के मूल्यों को पॉप्युलेट करता है। लेकिन इसके लिए आपकी फॉर्म कुंजी को आपके मॉडल में गुणों के नाम से मेल खाना चाहिए और यदि ऐसा है तो आपका मॉडल सही तरीके से पॉप्युलेट हो गया है। अब हम वास्तविक प्रश्न पर आते हैं: UpdateModel क्या करता है? सरल जवाब मॉडल बाध्यकारी के अलावा कुछ भी नहीं है। अंतर केवल इतना है कि आप इसे स्पष्ट रूप से कहते हैं।ऊपर ActionResult UpdateModel

Public ActionResult Index() 
{ 
    UserViewModel vm = new UserViewModel(); 
    UpdateModel(vm);// it will do same thing that was previously handled automatically by mvc 
} 

का उपयोग कर अब, स्वत: मॉडल बंधन स्पष्ट मॉडल के रूप में अच्छी तरह से बाध्यकारी द्वारा नियंत्रित नहीं किया जाएगा द्वारा नियंत्रित नहीं किया गया था क्या की तरह फिर से लिखा जा सकता क्योंकि इसका अपने html के साथ अपने समस्या बांधने की मशीन मॉडल के साथ नहीं समस्या । आपके जैसे नेस्टेड दृश्य मॉडल के साथ, प्रपत्र फ़ील्ड नाम सावधानी से गढ़ी किया जाना चाहिए ताकि MVC सही ढंग से आप

vm.BA.StatesTraveledTo = statesCheckBoxes.Split(',').ToList<string>(); 

की तरह कुछ लिखने के लिए और अगर आप इस तरह की बात जांच नहीं करना चाहती बिना अपने मॉडल के लिए यह इंजेक्षन कर सकते हैं इस google search

2

यहाँ यह के लिए स्रोत कोड है: http://aspnet.codeplex.com/SourceControl/changeset/view/72551#266451

यह बहुत आसान है,

protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IDictionary<string, ValueProviderResult> valueProvider) where TModel : class { 
     if (model == null) { 
      throw new ArgumentNullException("model"); 
     } 
     if (valueProvider == null) { 
      throw new ArgumentNullException("valueProvider"); 
     } 

     Predicate<string> propertyFilter = propertyName => BindAttribute.IsPropertyAllowed(propertyName, includeProperties, excludeProperties); 
    IModelBinder binder = Binders.GetBinder(typeof(TModel)); 

    ModelBindingContext bindingContext = new ModelBindingContext() { 
     Model = model, 
     ModelName = prefix, 
     ModelState = ModelState, 
     ModelType = typeof(TModel), 
     PropertyFilter = propertyFilter, 
     ValueProvider = valueProvider 
    }; 
    binder.BindModel(ControllerContext, bindingContext); 
    return ModelState.IsValid; 
} 

थी एस सिर्फ एक मॉडल बाइंडिंग कॉन्टेक्स्ट बनाता है और इसे बांधता है। मेरा मानना ​​है कि आपकी कार्रवाई को बुलाए जाने से पहले डिफ़ॉल्ट रूप से यह पहले से ही होता है। इसे मैन्युअल रूप से कॉल करना कभी दुर्लभ होता है।

बस यहां अनुमान लगाएं लेकिन आपको अजीब परिणाम मिल रहे हैं क्योंकि आप चीजों को एक असामान्य तरीके से कर रहे हैं। आपके कार्य का हस्ताक्षर:

public ActionResult Index(UserViewModel vm, FormCollection form) 

उपयोगकर्ता दृश्य दृश्य और एक फॉर्मकॉलिशन लेता है। आम तौर पर लोग एक या दूसरे करते हैं (वास्तव में फॉर्मकोलेक्शन आजकल बहुत दुर्लभ है)। दोबारा, मैं यहाँ स्मृति से बाहर जा रहा हूं लेकिन मुझे लगता है कि UpdateModel कुछ भी नहीं करता है क्योंकि वे मान पहले ही बाध्य हैं। यदि यह खाली है तो शायद ऐसा इसलिए है क्योंकि फॉर्मकॉलेक्शन आपके सभी सबमिट किए गए मान प्राप्त करता है (बाइंड्स) और दृश्यमान के लिए बाध्य करने के लिए कोई भी नहीं छोड़ा जाता है।

+0

धन्यवाद। मेरी नोबनेस क्षमा करें- आप कह रहे हैं कि UpdateModel() मेरी क्रिया से पहले डिफ़ॉल्ट रूप से चलाया जाता है इसलिए कार्रवाई से स्पष्ट रूप से चलाने की आवश्यकता नहीं है? – SaltProgrammer

+0

मैं फ़ॉर्मकोलेक्शन का उपयोग करने का कारण यह है कि डिफ़ॉल्ट मॉडल बाइंडर (व्यूमोडेल के लिए उपयोग किया गया) उपयोगकर्ताViewModel ऑब्जेक्ट के अंदर BankAccount ऑब्जेक्ट में मौजूद एक सूची संपत्ति के विरुद्ध मेरे पास चेकबॉक्स का एक सेट बाध्य नहीं कर सकता है। स्रोत कोड को अभी देखें जो मैंने अभी प्रश्न में जोड़ा है। उस गहरी घोंसले वाली संपत्ति को सही तरीके से मैप करने के लिए, मैं इसे फॉर्मकोलेक्शन से सीधे पकड़ता हूं। फॉर्मकोलेक्शन ऑब्जेक्ट का उपयोग न करने का दूसरा तरीका, जिसे मैं जानता हूं, एक कस्टम मॉडल बाइंडर बना रहा है, लेकिन मैं इसे इससे अधिक जटिल बनाना नहीं चाहता हूं, या क्या मुझे कुछ याद आ रहा है? – SaltProgrammer

+1

हाँ, बस उन अन्य मानों के लिए एक वर्ग बनाएं जो आप चेकबॉक्स के लिए उचित प्रकार के साथ चाहते हैं। यदि यह फॉर्मकोलेक्शन पर बाध्य कर सकता है तो इसे इसे स्थिर प्रकार से बांधने में सक्षम होना चाहिए। इसके अलावा आप अनुरोध ऑब्जेक्ट से सामान निकाल सकते हैं। –

0

अद्यतन मॉडल मूल रूप से आपके मौजूदा मॉडल में नए मान अपडेट करने के लिए उपयोग किया जाता है। आपको स्पष्ट रूप से मूल्य असाइन करने की आवश्यकता नहीं है।

+0

आप कह रहे हैं कि मुझे ऐसा करने की ज़रूरत नहीं है ... vm.BA.StatesTraveledTo = statesCheckBoxes.Split (',')। ToList (); ??? यदि मुझे ऐसा करने की ज़रूरत नहीं है, तो सिंटैक्स क्या है यदि मैं केवल UpdateModel() विधि का उपयोग करना चाहता हूं? – SaltProgrammer

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