How do I pass a Dictionary as a parameter to an ActionResult method from jQuery/Ajax?

后端 未结 6 1527
无人共我
无人共我 2020-11-30 05:27

I\'m using jQuery to make an Ajax call using an Http Post in ASP.NET MVC. I would like to be able to pass a Dictionary of values.

The closest thing I could think of

6条回答
  •  庸人自扰
    2020-11-30 05:58

    At last I figured it out!! Thanks for the suggestions everyone! I finally figured out the best solution is to pass JSON via the Http Post and use a custom ModelBinder to convert the JSON to a Dictionary. One thing I did in my solution is created a JsonDictionary object that inherits from Dictionary so that I can attach the custom ModelBinder to the JsonDictionary type, and it wont cause any conflicts in the future if I use Dictionary as a ActionResult parameter later on for a different purpose than JSON.

    Here's the final ActionResult method:

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

    And the jQuery "$.post" call:

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

    Then the JsonDictionaryModelBinder needs to be registered, I added this to the Application_Start method within the Global.asax.cs:

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

    And, finally here's the JsonDictionaryModelBinder object and JsonDictionary object I created:

    public class JsonDictionary : Dictionary
    {
        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(json);
        }
    }
    

提交回复
热议问题