-->

我如何通过一个字典作为参数传递给jQuery的从/阿贾克斯一个ActionResult方法?我如何通

2019-05-16 14:17发布

我使用jQuery做使用HTTP POST的ASP.NET MVC的Ajax调用。 我希望能够传递值的词典。

我能想到的最接近的是一个字符串的多维数组来传递,但实际上被传递到的ActionResult方法的结果是包含“键/值”对的字符串连接一维字符串数组。

例如下面的“值”数组中的第一项包含以下值:

"id,200"

这里是我的ActionResult方法的一个例子:

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

下面是我如何调用从jQuery的方法的例子:

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

有谁知道如何从jQuery的传递Dictionary对象到的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";

Answer 1:

最后我想通了! 感谢您的建议大家! 我终于想通了最好的解决方案是通过HTTP POST传递JSON和使用自定义模型绑定器的JSON转换成词典。 有一件事我在我的解决方案确实是创造了从字典继承,这样我可以将自定义模型绑定器的JsonDictionary类型JsonDictionary对象,它不会在未来造成任何冲突,如果我以后使用字典作为ActionResult的参数为不同的目的JSON。

下面是最终的ActionResult方法:

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

而jQuery的“$。员额”电话:

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

然后JsonDictionaryModelBinder需要注册,我已将此添加到Global.asax.cs中内Application_Start方法中:

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

而且,终于在这里是我创建的JsonDictionaryModelBinder对象和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);
    }
}


Answer 2:

这是我试过了。 节省了大量的工作。 使用Javascript:

  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; }

}


Answer 3:

这是可能的自定义模型粘合剂或过滤器。 幕后 - 你将不得不做手工反正(的Request.Form,解析字符串,创建字典TRALALA),但至少 - 您的控制器将是干净的代码将是可重复使用的另一个行动。



Answer 4:

我不认为这是可能通过HTTP POST从jQuery的/阿贾克斯字典传递给一个ActionResult方法。 有一件事我想通了,这似乎是最简单的一起工作是一个JSON对象传递,然后解析出到字典。

下面是从jQuery的发送JSON作为一个伪解释上述呼叫“.post的$”的修改后的版本:

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

该“Sys.Serialization.JavaScriptSerializer.serialize”功能是ASP.NET AJAX JavaScript库的方法。

下面是上述的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方法问题的工作。



Answer 5:

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");

更新:

如果你的价值观是在HTML的输入,然后在jQuery的你可以这样做:

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

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

更新:

同时检查: 斯科特Hanselman的ComputerZen.com - ASP.NET线格式模型绑定到数组,列表,集合,字典



Answer 6:

这是一个老的文章,但我不禁也不得不说几句话。

@ EU-GE-NE:“DefaultModelBinder能够到您的文章绑定到数组或字典。” 真实的,但至少在我的字典找到所需要的形式符号,而有悖常理。

@克里斯:我昨天完全一样的问题,而试图发布一个JavaScript(JSON)字典传送到控制器的操作方法。 我曾经指出,通用处理字典不同类型的参数完全不同的自定义模型粘合剂。 我只在MVC 3测试了它,可能有一个改进的框架的优势。

对于我的经历的细节和自定义模型绑定的源代码,请参阅我的博客文章在http://buildingwebapps.blogspot.com/2012/01/passing-javascript-json-dictionary-to.html



文章来源: How do I pass a Dictionary as a parameter to an ActionResult method from jQuery/Ajax?