[c#] पोस्ट जेसन शब्दकोश


4 Answers

एक दुर्भाग्यपूर्ण कामकाज:

data.dictionary = {
    'A': 'a',
    'B': 'b'
};

data.dictionary = JSON.stringify(data.dictionary);

. . .

postJson('/mvcDictionaryTest', data, function(r) {
    debugger;
}, function(a,b,c) {
    debugger;
});

postJSON जेएस lib समारोह (jQuery का उपयोग करता है):

function postJson(url, data, success, error) {
    $.ajax({
        url: url,
        data: JSON.stringify(data),
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        success: success,
        error: error
    });
}

ViewModel ऑब्जेक्ट पोस्ट किया जा रहा है (संभवतः एक शब्दकोश से ज्यादा चल रहा है):

public class TestViewModel
{
    . . .
    //public Dictionary<string, string> dictionary { get; set; }
    public string dictionary { get; set; }
    . . .
}

नियंत्रक विधि को पोस्ट किया जा रहा है:

[HttpPost]
public ActionResult Index(TestViewModel model)
{
    var ser = new System.Web.Script.Serialization.JavascriptSerializer();
    Dictionary<string, string> dictionary = ser.Deserialize<Dictionary<string, string>>(model.dictionary);

    // Do something with the dictionary
}
Question

मैं निम्नलिखित कोशिश कर रहा हूं: अंदर एक शब्दकोश के साथ एक मॉडल इसे पहले AJAX अनुरोध पर भेजता है, फिर परिणाम को फिर से क्रमबद्ध करें और इसे वापस नियंत्रक को भेजें।

यह परीक्षण करना चाहिए कि मैं अपने मॉडल में एक शब्दकोश वापस प्राप्त कर सकता हूं। यह काम नहीं करता है

मेरा सरल परीक्षण यहां दिया गया है:

public class HomeController : Controller
{
    public ActionResult Index (T a)
    {
      return View();
    }

    public JsonResult A(T t)
    {
      if (t.Name.IsEmpty())
      {
        t = new T();
        t.Name = "myname";
        t.D = new Dictionary<string, string>();
        t.D.Add("a", "a");
        t.D.Add("b", "b");
        t.D.Add("c", "c");
      }
      return Json(t);
    }
}

//model
public class T
{
  public string Name { get; set; }
  public IDictionary<string,string> D { get; set; }
}

जावास्क्रिप्ट:

$(function () {
    var o = {
        Name: 'somename',
        "D": {
            "a": "b",
            "b": "c",
            "c": "d"
        }
    };

    $.ajax({
        url: actionUrl('/home/a'),
        contentType: 'application/json',
        type: 'POST',
        success: function (result) {
            $.ajax({
                url: actionUrl('/home/a'),
                data: JSON.stringify(result),
                contentType: 'application/json',
                type: 'POST',
                success: function (result) {
                }
            });
        }
    });
});

जेसन को फायरबग में प्राप्त किया गया और जेसन भेजा गया समान है। मैं केवल कुछ मान सकता हूं कि रास्ते में कुछ खो जाता है।

किसी के पास यह विचार है कि मैं क्या गलत कर रहा हूं?




जटिल वस्तु को एक स्ट्रिंग के रूप में पोस्ट करें और दूसरी तरफ deserialize। हालांकि इसके लिए कोई प्रकार की सुरक्षा नहीं है। स्ट्रिंग कुंजी और स्ट्रिंग सरणी मानों वाला एक शब्दकोश यहां दिया गया है।

js:

var data = { 'dictionary': JSON.stringify({'A': ['a', 'b'] }) };

$.ajax({
    url: '/Controller/MyAction',
    data: JSON.stringify(data),
    type: 'POST',
    contentType: 'application/json',
    dataType: 'json'
});

सी # नियंत्रक:

[HttpPost]
public ActionResult MyAction(string dictionary)
{
    var s = new System.Web.Script.Serialization.JavaScriptSerializer();
    Dictionary<string, string[]> d = s.Deserialize<Dictionary<string, string[]>>(dictionary);
    return View();
}



मुझे इसे कस्टम मॉडल बाइंडर के साथ काम करने और डेटा भेजने के तरीके को बदलने के लिए मिला; Stringify और सामग्री प्रकार सेट करने के बिना।

जावास्क्रिप्ट:

    $(function() {
        $.ajax({
            url: '/home/a',
            type: 'POST',
            success: function(result) {
                $.ajax({
                    url: '/home/a',
                    data: result,
                    type: 'POST',
                    success: function(result) {

                    }
                });
            }
        });
    });

कस्टम मॉडल बांधने की मशीन:

public class DictionaryModelBinder : IModelBinder
{          
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
            throw new ArgumentNullException("bindingContext");

        string modelName = bindingContext.ModelName;
        IDictionary<string, string> formDictionary = new Dictionary<string, string>();

        Regex dictionaryRegex = new Regex(modelName + @"\[(?<key>.+?)\]", RegexOptions.CultureInvariant);
        foreach (var key in controllerContext.HttpContext.Request.Form.AllKeys.Where(k => k.StartsWith(modelName + "[")))
        {
            Match m = dictionaryRegex.Match(key);
            if (m.Success)
            {
                formDictionary[m.Groups["key"].Value] = controllerContext.HttpContext.Request.Form[key];
            }
        }
        return formDictionary;
    }
}

और ग्लोबल.एक्सएक्स में मॉडल बाइंडर जोड़कर:

ModelBinders.Binders[typeof(IDictionary<string, string>)] = new DictionaryModelBinder();



हाल ही में इस समस्या पर आने वाले किसी भी व्यक्ति के लिए, जब तक आपको विशेष रूप से एक शब्दकोश को स्वीकार करने के लिए अपने नियंत्रक की आवश्यकता नहीं है, तो आप निम्न कार्य कर सकते हैं:

HttpResponseMessage SomeMethod([FromBody] IEnumerable<KeyValuePair<Key, Value>> values)
{
    Dictionary<Key, Value> dictionary = values.ToDictionary(x => x.Key, x = x.Value);
}

हालांकि यह थोड़ा हैकी है।




बस एक बेहतर deserializer का उपयोग करें। वह पहली पंक्ति जहां मैंने स्थिति निर्धारित की है क्योंकि JsonValueProvider अंत में स्ट्रीम छोड़ देता है। अधिक एमएस JSON विफल।

Request.InputStream.Position = 0;
var reader = new StreamReader(Request.InputStream);

var model = Newtonsoft.Json.JsonConvert.DeserializeObject<CreativeUploadModel>(reader.ReadToEnd());

तो कहीं उस CreativeUploadModel ऑब्जेक्ट ग्राफ़ में इस तरह का एक प्रोप है:

public Dictionary<string, Asset> Assets { get; set; }

जो deserialized है (उदाहरण के लिए):

"assets":{"flash":{"type":"flash","value":"http://1234.cloudfront.net/1234.swf","properties":"{\"clickTag\":\"clickTAG\"}"}

Newtonsoft JSON वेबएपीआई के लिए डिफ़ॉल्ट JSON प्रदाता है ... इसलिए यह कहीं भी नहीं जा रहा है।






Related