2009-08-19 9 views
11

क्या ऐसी संपत्ति को बांधना संभव है?एएसपी एमवीसी.नेट - कैसे KeyValuePair बांधने के लिए?

public KeyValuePair<string, string> Stuff { get; set; } 

मैं ध्यान में रखते हुए निम्नलिखित कोड का उपयोग करने की कोशिश की है, लेकिन यह काम नहीं करता है:

<%=Html.Text("Stuff", Model.Stuff.Value)%>  
<%=Html.Hidden("Model.Stuff.Key", Model.Stuff.Key)%> 
+0

कृपया वर्णन करें कि "यह काम नहीं करता" का अर्थ है। –

+0

बिल्कुल क्या काम नहीं करता है? क्या आप थोड़ा सा विस्तार कर सकते हैं? – Jimmeh

+0

मैं डेटा को संसाधित करने की कोशिश कर रहा हूं जिसे देखने पर अपडेट किया गया है, इसलिए नियंत्रक में मुझे सही अद्यतन मॉडल मिल रहा है, लेकिन इस विशेष संपत्ति का कोई मूल्य नहीं है। मेरे मामले में यह [शून्य, शून्य] है। –

उत्तर

8

KeyValuePair<K,V> एक संरचना है, कक्षा नहीं है, इसलिए आपकी Stuff संपत्ति पर प्रत्येक कॉल मूल KeyValuePair की प्रतिलिपि देता है। इसलिए, जब आप Model.Stuff.Value और Model.Stuff.Key पर बाध्य करते हैं, तो आप वास्तव में KeyValuePair<K,V> के दो अलग-अलग उदाहरणों पर काम कर रहे हैं, इनमें से कोई भी आपके मॉडल से नहीं है। इसलिए जब वे अपडेट होते हैं, तो यह आपके मॉडल में स्टफ प्रॉपर्टी को अपडेट नहीं करता है ... QED

वैसे, कुंजी और मूल्य गुण केवल पढ़ने के लिए हैं, इसलिए आप उन्हें संशोधित नहीं कर सकते हैं: आपको KeyValuePair उदाहरण की जगह

निम्नलिखित तरीके को काम करना चाहिए:

मॉडल:

private KeyValuePair<string, string> _stuff; 
public KeyValuePair<string, string> Stuff 
{ 
    get { return _stuff; } 
    set { _stuff = value; } 
} 

public string StuffKey 
{ 
    get { return _stuff.Key; } 
    set { _stuff = new KeyValuePair<string, string>(value, _stuff.Value); } 
} 

public string StuffValue 
{ 
    get { return _stuff.Value; } 
    set { _stuff = new KeyValuePair<string, string>(_stuff.Key, value); } 
} 

दृश्य:

<%=Html.Text("Stuff", Model.StuffValue)%>  
<%=Html.Hidden("Model.StuffKey", Model.StuffKey)%> 
+1

कामकाज के लिए धन्यवाद, यह काम करता है। यह सुंदर नहीं दिखता है, लेकिन यह इस मामले के लिए पर्याप्त है। –

+0

ऐसा लगता है कि इसके लिए कक्षा का उपयोग करना क्लीनर है। यह निराशाजनक है - अधिक कोड (ऊपर के रूप में) या किसी अन्य वर्ग। एचआरएम ... यह पूछने के लिए धन्यवाद। – Cymen

+0

इसके अलावा [यह] (http://khalidabuhakmeh.com/submitting-a-dictionary-to-an-asp-net-mvc-action), 'शब्दकोश' का उपयोग करके पोस्ट किसी की मदद कर सकता है। – stom

0
<%=Html.Text("Stuff.Value", Model.Stuff.Value)%> 

काम सकता है?

+0

मैंने कोशिश की लेकिन परिणाम भी वही है। –

0

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

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

यदि आपको कभी भी किसी जटिल ऑब्जेक्ट से जुड़ने की आवश्यकता है, यानी शब्दकोश तो आपको प्रत्येक संपत्ति के लिए एक टेक्स्टबॉक्स होना चाहिए, जिसमें लेख के समान संपत्ति में ड्रिलिंग अभिव्यक्ति हो।

http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx

public class SomeVM 
    { 
     public Dictionary<string, string> Fields { get; set; } 
    } 

    public class HomeController : Controller 
    { 
     [HttpGet] 
     public ViewResult Edit() 
     { 
      SomeVM vm = new SomeVM 
      { 
      Fields = new Dictionary<string, string>() { 
        { "Name1", "Value1"}, 
        { "Name2", "Value2"} 
       } 
      }; 

      return View(vm); 

     } 

     [HttpPost] 
     public ViewResult Edit(SomeVM vm) //Posted values in vm.Fields 
     { 
      return View(); 
     } 
    } 

CSHTML: मान के लिए

संपादकों केवल (बेशक आप LabelFor कुंजी के आधार पर लेबल उत्पन्न करने के लिए जोड़ सकते हैं):

@model MvcApplication2.Controllers.SomeVM 

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 

    <fieldset> 
     <legend>SomeVM</legend> 

     @foreach(var kvpair in Model.Fields) 
     { 
      @Html.EditorFor(m => m.Fields[kvpair.Key]) //html: <input name="Fields[Name1]" …this is how the model binder knows during the post that this textbox value gets stuffed in a dictionary named “Fields”, either a parameter named Fields or a property of a parameter(in this example vm.Fields). 
     } 

     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
} 

दोनों कुंजी का संपादन/मान : @ {var fields = Model.Fields.ToList(); }

@for (int i = 0; i < fields.Count; ++i) 
    { 
     //It is important that the variable is named fields, to match the property name in the Post method's viewmodel. 
     @Html.TextBoxFor(m => fields[i].Key) 
     @Html.TextBoxFor(m => fields[i].Value) 

     //generates using integers, even though the dictionary doesn't use integer keys, 
     //it allows model binder to correlate the textbox for the key with the value textbox:    
     //<input name="fields[0].Key" ... 
     //<input name="fields[0].Value" ... 

     //You could even use javascript to allow user to add additional pairs on the fly, so long as the [0] index is incremented properly 
    } 
0

मुझे पता है कि यह एक छोटा सा सवाल है, लेकिन मुझे सुझाए गए समाधान में से कोई भी पसंद नहीं आया, इसलिए मैं अपना देता हूं। मैंने KeyValuePairs को संभालने के लिए डिफ़ॉल्ट मॉडल बाइंडर को फिर से लिखा है, इसलिए मैं उन्हें पहले के रूप में उपयोग कर सकता हूं।

public class CustomModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var model = base.BindModel(controllerContext, bindingContext);    
     model = ResolveKeyValuePairs(bindingContext, model); 
     return model; 
    } 

    private object ResolveKeyValuePairs(ModelBindingContext bindingContext, object model) 
    { 
     var type = bindingContext.ModelType; 
     if (type.IsGenericType) 
     { 
      if (type.GetGenericTypeDefinition() == typeof (KeyValuePair<,>)) 
      {      
       var values = bindingContext.ValueProvider as ValueProviderCollection; 
       if (values != null) 
       { 
        var key = values.GetValue(bindingContext.ModelName + ".Key"); 
        var keyValue = Convert.ChangeType(key.AttemptedValue, bindingContext.ModelType.GetGenericArguments()[0]); 
        var value = values.GetValue(bindingContext.ModelName + ".Value"); 
        var valueValue = Convert.ChangeType(value.AttemptedValue, bindingContext.ModelType.GetGenericArguments()[1]); 
        return Activator.CreateInstance(bindingContext.ModelType, new[] {keyValue, valueValue}); 
       } 

      } 
     } 
     return model; 
    } 
संबंधित मुद्दे