2009-07-03 15 views
11

मैं एएसपी.नेट एमवीसी में एक एचटीपी पोस्ट का उपयोग कर अजाक्स कॉल करने के लिए jQuery का उपयोग कर रहा हूं। मैं मूल्यों का एक शब्दकोश पास करने में सक्षम होना चाहता हूं।मैं jQuery/Ajax से ActionResult विधि में पैरामीटर के रूप में एक शब्दकोश को कैसे पास करूं?

सबसे नज़दीकी चीज जो मैं सोच सकता था वह स्ट्रिंग्स की बहु-आयामी सरणी में गुजरना था, लेकिन परिणाम जो वास्तव में एक्शनआरसल्ट विधि में पास हो जाता है वह एक आयामी स्ट्रिंग सरणी है जिसमें "कुंजी/मान" की स्ट्रिंग कॉन्सटेनेशन होती है "जोड़ी।

public ActionResult AddItems(string[] values) 
{ 
    // do something 
} 

यहाँ मैं कैसे 'का एक उदाहरण है:

"id,200" 

यहाँ मेरी ActionResult विधि का एक उदाहरण है:

उदाहरण के लिए नीचे दिए गए "मूल्यों" सरणी में पहला आइटम नीचे मान मैं jQuery से विधि को कॉल कर रहा हूं:

$.post("/Controller/AddItems", 
    { 
     values: [ 
      ["id", "200"], 
      ["FirstName", "Chris"], 
      ["DynamicItem1", "Some Value"], 
      ["DynamicItem2", "Some Other Value"] 
     ] 
    }, 
    function(data) { }, 
    "json"); 

क्या कोई जानता है कि एक शब्दकोश को कैसे पास किया जाए एक ऐरे के बजाय jQuery से ActionResult विधि से इंजेक्शन?

मैं वास्तव में इस तरह मेरी ActionResult परिभाषित करना चाहते हैं:

public ActionResult AddItems(Dictionary<string, object> values) 
{ 
    // do something 
} 

कोई सुझाव?

अद्यतन: मैंने मूल्य के भीतर एक अल्पविराम में गुजरने की कोशिश की और मूल रूप से स्ट्रिंग पार्सिंग का उपयोग करके कुंजी/मूल्य जोड़ी को वास्तव में पार्स करना असंभव बना देता है।

पास इस: इस में

values: [ 
    ["id", "200,300"], 
    ["FirstName", "Chris"] 
] 

परिणाम:

values[0] = "id,200,300"; 
values[1] = "FirstName,Chris"; 
+0

मुझे नहीं लगता कि वहाँ है.मुझे ऐसा करने के लिए गलत हो सकता है एक तरीका है, लेकिन यह डेटा एक के रूप में में पारित कर दिया पार्स करने के लिए तुच्छ हो जाएगा स्ट्रिंग सरणी, और AddItems विधि के अंदर स्वयं को शब्दकोश बनाएं। –

+0

यह सुनिश्चित नहीं है कि मूल्यों के भीतर किसी भी अल्पविराम के कारण कौन से पार्सिंग समस्याएं होंगी। –

+0

आखिर में मैंने इसे समझ लिया, धन्यवाद जिन्होंने सभी सुझाव दिए! मैंने अपना अंतिम समाधान नीचे दिए गए उत्तर के रूप में जोड़ा। जैसे ही एसओ मुझे देता है, मैं इसे सही उत्तर के रूप में चिह्नित करूंगा। सबको धन्यवाद! –

उत्तर

11

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

public ActionResult AddItems([Bind(Include="values")] JsonDictionary values) 
{ 
    // do something 
} 

और jQuery "$ .post" कॉल:

$.post("/Controller/AddItems", 
{ 
    values: Sys.Serialization.JavaScriptSerializer.serialize(
      { 
       id: 200, 
       "name": "Chris" 
      } 
     ) 
}, 
function(data) { }, 
"json"); 

फिर JsonDictionaryModelBinder जरूरत पंजीकृत होने के लिए, मैं भीतर Application_Start विधि को यह जोड़ा

यहाँ अंतिम ActionResult विधि है Global.asax.cs:

protected void Application_Start() 
{ 
    ModelBinders.Binders.Add(typeof(JsonDictionary), new JsonDictionaryModelBinder()); 
} 

और अंततः जेसन डिक्शनोड lBinder वस्तु और JsonDictionary वस्तु मेरे द्वारा बनाए गए:

public class JsonDictionary : Dictionary<string, object> 
{ 
    public JsonDictionary() { } 

    public void Add(JsonDictionary jsonDictionary) 
    { 
     if (jsonDictionary != null) 
     { 
      foreach (var k in jsonDictionary.Keys) 
      { 
       this.Add(k, jsonDictionary[k]); 
      } 
     } 
    } 
} 

public class JsonDictionaryModelBinder : IModelBinder 
{ 
    #region IModelBinder Members 

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     if (bindingContext.Model == null) { bindingContext.Model = new JsonDictionary(); } 
     var model = bindingContext.Model as JsonDictionary; 

     if (bindingContext.ModelType == typeof(JsonDictionary)) 
     { 
      // Deserialize each form/querystring item specified in the "includeProperties" 
      // parameter that was passed to the "UpdateModel" method call 

      // Check/Add Form Collection 
      this.addRequestValues(
       model, 
       controllerContext.RequestContext.HttpContext.Request.Form, 
       controllerContext, bindingContext); 

      // Check/Add QueryString Collection 
      this.addRequestValues(
       model, 
       controllerContext.RequestContext.HttpContext.Request.QueryString, 
       controllerContext, bindingContext); 
     } 

     return model; 
    } 

    #endregion 

    private void addRequestValues(JsonDictionary model, NameValueCollection nameValueCollection, ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     foreach (string key in nameValueCollection.Keys) 
     { 
      if (bindingContext.PropertyFilter(key)) 
      { 
       var jsonText = nameValueCollection[key]; 
       var newModel = deserializeJson(jsonText); 
       // Add the new JSON key/value pairs to the Model 
       model.Add(newModel); 
      } 
     } 
    } 

    private JsonDictionary deserializeJson(string json) 
    { 
     // Must Reference "System.Web.Extensions" in order to use the JavaScriptSerializer 
     var serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); 
     return serializer.Deserialize<JsonDictionary>(json); 
    } 
} 
1

यह कस्टम मॉडल बाइंडरों या फिल्टर के साथ संभव है। दृश्यों के पीछे - आपको इसे मैन्युअल रूप से करना होगा (Request.Form, पार्स स्ट्रिंग्स, डिक्शनरी ट्रलाला बनाएं), लेकिन कम से कम - आपका कंट्रोलर साफ़ होगा और कोड किसी अन्य क्रिया के लिए पुन: प्रयोज्य होगा।

1

मुझे नहीं लगता कि jQuery/Ajax से एक शब्दकोश में एक एचटीपी पोस्ट के माध्यम से एक एक्शन रिसेट विधि में पास करना संभव है। एक चीज जिसे मैंने पाया है कि जेएसओएन ऑब्जेक्ट में पास करना और फिर एक शब्दकोश में इसे पार्स करना है, उसके साथ काम करना सबसे आसान लगता है।

यहाँ jQuery से ऊपर बुला "$ .post" एक छद्म शब्दकोश के रूप में JSON भेजता है की की संशोधित संस्करण है:

$.post("/Controller/AddItems", 
    { 
     values: Sys.Serialization.JavaScriptSerializer.serialize(
       { 
        id: 200, 
        "name": "Chris" 
       } 
      ) 
    }, 
    function(data) { }, 
    "json"); 

"Sys.Serialization.JavaScriptSerializer.serialize" समारोह एक विधि है ASP.NET AJAX जावास्क्रिप्ट लाइब्रेरी का।

यहाँ ऊपर ActionResult विधि का संशोधित संस्करण है:

public ActionResult AddItems(Dictionary<string, object> values) 
{ 
    // Must Reference "System.Web.Extensions" in order to use the JavaScriptSerializer 
    var json = new System.Web.Script.Serialization.JavaScriptSerializer(); 
    var data = json.Deserialize<Dictionary<string, string>>(routeValues); 

    // do something 
} 

मैं इस JSON गुजर, बजाय भेजने के लिए फार्म संग्रह का उपयोग करके इसे ज्यादा यूनिट टेस्ट के लिए आसान बना देता है लगता है/कुंजी के संग्रह को पुनः प्राप्त/मूल्य जोड़ेसाथ ही, एक कस्टम IModelBinder बनाने के तरीके को समझने से काम करना आसान है, और एक कस्टम IModelBinder अन्य ActionResult विधियों के साथ समस्याएं पैदा कर सकता है जब यह केवल मुझे ऐसा करने की आवश्यकता है।

+0

क्रिस, ऊपर मेरी टिप्पणी देखें। मुझे अभी भी लगता है कि आप इस बारे में कठिन तरीके से जा रहे हैं। मैं 100% निश्चित नहीं हूं लेकिन मुझे यह निंदा लग रहा है कि आप हैं। – griegs

0

DefaultModelBinder आपके पोस्ट को सरणी या शब्दकोश में बाध्य करने में सक्षम है।

सरणियों के लिए

:

public ActionResult AddItems(string[] values) 

$.post("/Controller/AddItems", { values: "values[0]=200&values[1]=300" }, 
    function(data) { }, "json"); 

या:

$.post("/Controller/AddItems", { values: "values=200&values=300" }, 
    function(data) { }, "json"); 
शब्दकोशों के लिए

: उदाहरण के लिए

public ActionResult AddItems(Dictionary<string, object> values) 

$.post("/Controller/AddItems", { 
    values: "values[0].Key=value0&values[0].Value=200&values[1].Key=value1&values[1].Value=300" }, function(data) { }, "json"); 

UPDATED:

अपने मूल्यों jQuery में फिर HTML आदानों में हैं, तो आप कुछ इस तरह कर सकते हैं:

var postData = $('input#id1, input#id2, ..., input#idN").serialize(); 
// or 
var postData = $('input.classOfYourInputs").serialize(); 

$.post("/Controller/AddItems", { values: postData }, function(data) { }, "json"); 

UPDATED:

इसके अलावा इस जाँच: Scott Hanselman's ComputerZen.com - ASP.NET Wire Format for Model Binding to Arrays, Lists, Collections, Dictionaries

+0

मैंने आपके शब्दकोश उदाहरण की कोशिश की, लेकिन यह "मान" पैरामीटर को पॉप्युलेट करने का अंत नहीं करता है; यह सिर्फ एक खाली शब्दकोश होने के समाप्त होता है। –

+0

क्या आपने शब्दकोश <स्ट्रिंग, स्ट्रिंग> मूल्यों के बजाय शब्दकोश को आजमाया था। यह भी जांचें कि क्या आपके मान [n] अनुक्रमणिका शून्य आधारित और अखंड हैं। Http://stackoverflow.com/questions/1031416/asp-net-mvc-model-binding-a-set-of- गतिशील- जनरेटेड- चेकबॉक्स-how-to/1031694#1031694 भी –

0

यह एक पुरानी पोस्ट है, लेकिन मैं वैसे भी कुछ टिप्पणी कर रहा मदद नहीं कर सकता।

@ eu-ge-ne: "DefaultModelBinder आपके पोस्ट को सरणी या शब्दकोश में बाध्य करने में सक्षम है।" सच है लेकिन कम से कम शब्दकोशों के लिए मुझे आवश्यक फॉर्म नोटेशन बल्कि counterintuitive मिलते हैं।

@ क्रिस: कल जावास्क्रिप्ट (JSON) शब्दकोश को नियंत्रक क्रिया विधि में पोस्ट करने का प्रयास करते समय मुझे वही समस्या थी। मैंने एक पूरी तरह से अलग कस्टम मॉडल बाइंडर का काम किया जो विभिन्न प्रकार के तर्कों के साथ जेनेरिक शब्दकोशों को संसाधित करता है। मैंने केवल एमवीसी 3 में इसका परीक्षण किया है और शायद एक बेहतर ढांचे का लाभ उठाया है।

अपने अनुभवों का विवरण और कस्टम मॉडल बांधने की मशीन के स्रोत कोड के लिए, कृपया http://buildingwebapps.blogspot.com/2012/01/passing-javascript-json-dictionary-to.html

2

पर अपने ब्लॉग पोस्ट देखें यह है कि मैं क्या करने की कोशिश की है। बहुत सारे काम बचाता है। जावास्क्रिप्ट:

var dict = {};  
     dict["id"] = "200"; 
     dict["FirstName"] = "Chris"; 
     dict["DynamicItem1"] = "Some Value"; 
     dict["DynamicItem2"] = "Some Other Value"; 

     var theObject = {}; 
     theObject.dict = dict; 
     $.post(URL, theObject, function (data, textStatus, XMLHttpRequest) { 
      console.log("success"); 
     }, "json"); 

कार्रवाई विधि:

public ActionResult MethodName(DictionaryModel obj) 
    { 
     //Action method logic 
    } 

public class DictionaryModel 
{ 
    public Dictionary<string, string> dict { get; set; } 

} 
+0

बिल्कुल वही नहीं जो मैं चाहता था, क्योंकि किसी ऑब्जेक्ट को पास करने का कोई मतलब नहीं है, अगर आप केवल शब्दकोश को पास कर सकते हैं लेकिन यह काफी अच्छा काम करता है। Upvoted। :) –

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

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