2010-02-16 11 views
7

मेरे पास ऐसा कुछ सामान्य स्थिति है जहां मुझे फॉर्म ऑर्डर को "ऑर्डर" मॉडल में बाध्य करने की आवश्यकता है। यह मॉडल इसे करने के लिए जानकारी के कुछ स्तर हैं:नेस्टेड स्तरों के साथ डिफॉल्टमोडेल बाइंडर समस्या + अन्य बाइंडर्स

Order.Billing.FirstName 
Order.Billing.Address.City 
Order.Billing.Address.Country 

DefaultModelBinder का उपयोग करना, अगर मैं एक कार्रवाई है कि परम, निम्नलिखित क्षेत्रों JustWork (टीएम) के रूप में इस आदेश मॉडल लेता है के लिए एक फार्म पोस्ट:

<%=Html.TextBox("Billing.FirstName")%> 
<%=Html.TextBox("Billing.Address.City")%> 

यह फ़ील्ड नहीं करता है:

<%=Html.TextBox("Billing.Address.Country")%> 

शिकन मैं देश संपत्ति के साथ है। हमारे मामले में, पता। देश एक देश वर्ग उदाहरण (आईएसओ 2/3/नाम/कोड तर्क) देता है। यह एक स्ट्रिंग नहीं है। आश्चर्य नहीं है कि यह डिफ़ॉल्ट रूप से काम नहीं करता है।

मेरा पहला विचार देश मॉडेलबिंडर (डिफॉल्टमोडेल बाइंडर का उत्तराधिकारी) और मॉडलबिंडर्स। बाइंडर्स बनाना था। इसे देश के प्रकार में जोड़ें। जब मैं ऐसा करता हूं, CountryModelBinder को उपरोक्त scenerio में कभी नहीं बुलाया जाता है।

मेरा दूसरा विचार एक पता मॉडललबिंडर (डिफ़ॉल्ट मॉडेलबिन्डर का उत्तराधिकारी) बनाना था और इसे हमारे पता प्रकार से बांधना था। हालांकि इसे कॉल किया जाता है, "देश" के लिए सेटप्रोपर्टी कॉल का खाली मूल्य होता है, भले ही फ़ॉर्म ने "बिलिंग.एड्रेस.कंट्री" नामक फ़ील्ड पोस्ट किया हो।

कुछ टिंकरिंग के बाद, ऐसा लगता है कि मॉडल बाध्यकारी व्यवहार केवल CreateModel को कॉल करता है जब मॉडल शीर्ष स्तर की कक्षा है, जो कार्रवाई चाहता है, और अन्य सभी बाइंडर्स में उनके बाइंडप्रॉपरी/सेटप्रोपर्टी को बाल गुणों के लिए बुलाया जाता है।

दूसरे शब्दों में, यदि मैं ऑर्डर, ऑर्डर एड्रेस (बिलिंग), पता और देश के लिए मॉडल बाइंडर्स बना देता हूं। ऑर्डर लेने वाली कार्रवाई के लिए, केवल ऑर्डरमोडेल बाइंडर। क्रेट मॉडेल कहा जाता है। ORderAddress और पता। बाइंडप्रोपर्टी/सेटप्रोपर्टी को कुछ चीजों के लिए बुलाया जाता है, और कभी-कभी सेटप्रोपर्टी मान तर्क खाली होता है जब इसे किसी ऐसे नाम में स्पष्ट रूप से पोस्ट किया गया था जो अन्य फ़ील्ड प्रॉपर्टी मैपिंग से मेल खाता है।

बिलिंग को खींचने के लिए ऑर्डरमोडेल बाइंडर को कोड जोड़ने के लिए बस इतना आसान है। एड्रेस। Request.Form से बाहर निकलें। लेकिन मेरे पास कई मॉडल हैं जो पता का उपयोग करते हैं और उनमें से सभी को तोड़ने लगता है।

मुझे यहां क्या याद आ रही है? क्या इस मामले में CountryModelBinder वास्तव में कॉल करने का कोई तरीका है? मुझे लगता है कि देश मॉडेलबिन्डर को बिलिंग के दौरान बुलाया जाना चाहिए। एड्रेस। काउंटर को पता बांधने की देश की संपत्ति में मैप किया गया है।

+0

यह आपकी मदद कर सकता है: http://stackoverflow.com/questions/2462506/model-binding-with-nested-child-models-and-partialviews-in-asp-net-mvc – Will

+0

मुझे एक ही समस्या है एक नेस्टेड मॉडल संरचना के साथ, मुझे लगता है कि शीर्ष स्तर पर गुण, और एक स्तर नीचे बंधे हुए हैं, लेकिन उससे कम कुछ भी अनदेखा लगता है। क्या यह मॉडल बाइंडर का सामान्य व्यवहार है? बल्कि मनमाना व्यवहार लगता है। – UpTheCreek

उत्तर

0

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

यह पता चलता है कि यह काम करता है, और के रूप में भी उत्पादन स्तर कोड के करीब नहीं देखा जाना चाहिए अवधारणा का सिर्फ एक सबूत है:

मॉडल:

public class SimpleModel 
    { 
     public string Value { get; set; } 
     public int Other { get; set; } 
    } 

    public class ComplexModel 
    { 
     public SimpleModel Complexity {get;set;} 
     public string StrVal { get; set; } 
    } 

कुछ बांधने की मशीन:

public class MBinder : IModelBinder 
     { 
      public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
      { 
       if (bindingContext.ModelType == typeof(SimpleModel)) 
       { 
        var simpleModel= new SimpleModel(); 
        simpleModel.Other = 1; 
        simpleModel.Value = controllerContext.HttpContext.Request.Form["Complexity"]; 

        return cm; 
       } 
       return null; 
      } 
     } 
वैश्विक asax में

:

ModelBinders.Binders.Add(typeof (SimpleModel), new MBinder()); 
दृश्य में

कोड:

@model ComplexModel 

    @using (Html.BeginForm()) 
{ 
    <fieldset> 
     @Html.LabelFor(x => x.Complexity) 
     @Html.TextBoxFor(x => x.Complexity) 
    </fieldset> 

    <fieldset> 
     @Html.LabelFor(x => x.StrVal) 
     <br /> 
     @Html.EditorFor(x => x.StrVal) 
    </fieldset> 
    <input type="submit" /> 
} 

नियंत्रक:

public ActionResult Index() 
     { 
      return View(); 
     } 

     [HttpPost] 
     public ActionResult Index(ComplexModel model) 
     { 
      return RedirectToAction("Index"); 

     } 

BTW MVC 3 में एक बेहतर विकल्प IModelBinderProvider इंटरफेस का उपयोग करने होगा, लेकिन मैं सिर्फ कुछ है कि काम करेगा दिखाना चाहते थे।

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