2012-12-19 20 views
7

मेरे पास इस तरह की एक क्रिया विधि है।DefaultModelBinder और विरासत वाले वस्तुओं का संग्रह

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create(Form newForm) 
{ 
    ... 
} 

मेरे पास निम्न वर्गों वाला एक मॉडल है, जिसे मैं AJAX JSON डेटा से डेटा लोड करना चाहता हूं।

public class Form 
{ 
    public string title { get; set; } 

    public List<FormElement> Controls { get; set; } 

} 

public class FormElement 
{ 
    public string ControlType { get; set; } 

    public string FieldSize { get; set; } 
} 

public class TextBox : FormElement 
{ 
    public string DefaultValue { get; set; } 
} 

public class Combo : FormElement 
{ 
    public string SelectedValue { get; set; } 
} 

यहां JSON डेटा है।

{ "title": "FORM1", 
"Controls": 
[ 
{ "ControlType": "TextBox", "FieldSize": "Small" ,"DefaultValue":"test"}, 
{ "ControlType": "Combo", "FieldSize": "Large" , "SelectedValue":"Option1" } 
] 
} 


$.ajax({ 
       url: '@Url.Action("Create", "Form")', 
       type: 'POST', 
       dataType: 'json', 
       data: newForm, 
       contentType: 'application/json; charset=utf-8', 
       success: function (data) { 
        var msg = data.Message; 
       } 
      }); 

डिफ़ॉल्ट मॉडेलबिंडर नेस्टेड ऑब्जेक्ट संरचना को संभालने वाला है लेकिन यह विभिन्न उप वर्गों को हल नहीं कर सकता है।

संबंधित उप-वर्गों के साथ सूची लोड करने का सबसे अच्छा तरीका क्या होगा?

+0

क्या आप आगे विस्तार से समझा सकते हैं कि आप यहां क्या करने की कोशिश कर रहे हैं? ऐसा लगता है कि आप पूरे फॉर्म को केवल उस मूल्य के बजाय व्यूमोडेल में बांधने की कोशिश कर रहे हैं। मैं बैकएंड प्रदान करता है कुछ जेएसओएन डेटा के आधार पर गतिशील रूप से रूपों को उत्पन्न करने में बिंदु देख सकता हूं, लेकिन मैं यह समझने के लिए संघर्ष करता हूं कि जब आप उपयोगकर्ता फॉर्म में भरते हैं तो आप केवल मूल्यों के बजाय बैकएंड को संरचना क्यों प्रदान करना चाहते हैं। –

+0

मैं गतिशील रूप से फॉर्म उत्पन्न नहीं कर रहा हूं। मैं जेसन स्वीकार कर रहा हूं जो फॉर्म की संरचना का प्रतिनिधित्व करता है जिसे बाद में सिस्टम में सहेजा जाएगा। – Thurein

उत्तर

1

मैंने एमवीसी डिफॉल्टमोडेल बाइंडर कार्यान्वयन के कोड में देखा है। एक मॉडल को बाध्यकारी करते समय DefaultModelBinder GetModelProperties() का उपयोग कर मॉडल के गुणों को देखें।

protected virtual ICustomTypeDescriptor GetTypeDescriptor(ControllerContext controllerContext, ModelBindingContext bindingContext) { 
      return TypeDescriptorHelper.Get(bindingContext.ModelType); 
     } 

TypeDescriptorHelper.Get (मेरे मामले FormElement में) ModelType जो partent प्रकार है उपयोग कर रहा है, तो बच्चे के वर्ग (पाठ बॉक्स, कॉम्बो) के गुणों को पुनः प्राप्त नहीं कर रहे हैं: निम्नलिखित गुण देखने DefaultModelBinder कैसे है ।

आप विधि को ओवरराइड कर सकते हैं और नीचे दिए गए विशिष्ट बच्चे प्रकार को पुनर्प्राप्त करने के लिए व्यवहार को बदल सकते हैं।

protected override System.ComponentModel.PropertyDescriptorCollection GetModelProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) 
{ 
    Type realType = bindingContext.Model.GetType(); 
    return new AssociatedMetadataTypeTypeDescriptionProvider(realType).GetTypeDescriptor(realType).GetProperties(); 
} 


protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) 
     { 
      ValueProviderResult result; 
      result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".ControlType"); 

      if (result == null) 
       return null; 

      if (result.AttemptedValue.Equals("TextBox")) 
       return base.CreateModel(controllerContext, 
         bindingContext, 
         typeof(TextBox)); 
      else if (result.AttemptedValue.Equals("Combo")) 
       return base.CreateModel(controllerContext, 
         bindingContext, 
         typeof(Combo)); 
      return null; 
     }