将哈希表{}从javascript传递给mvc3控制器?

时间:2011-12-10 05:18:46

标签: javascript jquery asp.net-mvc-3

如何将以下内容传递回mmvc3控制器ActionResult?

var hashtable = {};
hashtable['screaming'] = ["1", "2"];
hashtable['mellow'] = ["3", "4", "5"];
$.get('@Url.Action("PerformMagic")', { 'theValues': hashtable }, function (data) {
    //Callback..    
});

我的控制器方法sig会是什么样的?

public ActionResult PerformMagic(/*What type goes here? string[] theValues or string[][] theValues)
{
}

2 个答案:

答案 0 :(得分:3)

如果要将哈希表值传递给动作,最自然的方法是将其作为字典传递给动作

public ActionResult PerformMagic(Dictionary<String, List<int>> theValues)
{
    // the magic!
}

当使用jQuery Ajax功能将值传递给ASP.NET MVC操作时,您将面临一个巨大的框架误解。 ASP.NET MVC ModelBinder期望使用此命名方案将值绑定到请求正文或URL中的Dictionary

theValues[0].key=key0
theValues[0].value[0]=values0.0
theValues[0].value[1]=values0.1
theValues[1].key=key1
theValues[1].value[0]=values1.0
theValues[1].value[1]=values1.1
theValues[1].value[2]=values1.2

This blog post提供了有关字典和列表的ASP.NET MVC命名方案的更多详细信息。

但jQuery使用此命名方案在请求正文或URL中传递值

theValues[key0][]=value0.0
theValues[key0][]=value0.1
theValues[key1][]=value1.0
theValues[key1][]=value1.1
theValues[key1][]=value1.2

在这两个例子中,我省略了'&amp;'并将请求值拆分为单独的行,以提高可读性。

因此,如果您想将值作为Dictionary传递给action方法,则需要使jQuery和ASP.NET MVC Model Binders交谈。我可以想到两个选择:

  1. 更改ASP.NET MVC对请求的预期命名方案 参数
  2. 更改jQuery用于构建的命名方案 请求参数
  3. 方法1要求您编写自己的Model Binder,并且由于绑定到Dictionary操作参数的命名功能隐藏在内部 UpdateDictionary 方法中,因此编写自己的Model Binder意味着要复制很多ASP.NET MVC DefaultModelBinder代码......

    方法2的实现应该相当简单,因为jQuery使用 param 函数来构建请求参数,而jQuery ajax 函数允许您只传入原始值由自定义函数转换以请求参数。关于jQuery ajax函数的更多细节可以是found here。请参阅“processData”部分。

    我将提供一个原型 jQuery实现,将 hashtable var作为字典参数传递给ASP.NET MVC控制器操作:

    function buildParams(prefix, dict) {
        var s = [],
        add = function (key, value) {
            // If value is a function, invoke it and return its value
            value = jQuery.isFunction(value) ? value() : value;
            s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
        };
    
        var i = 0;
    
        jQuery.each(dict, function (key, values) {
            add(prefix + '[' + i + '].key', key);
    
            jQuery.each(values, function (j, value) {
                add(prefix + '[' + i + '].value[' + j + ']', value);
            });
    
            i++;
        });
    
        return s.join('&');
    }
    
    $(function () {
        $('#submithashes').click(function (e) {
            var hashtable2 = {};
            hashtable2['screaming'] = ["1", "2"];
            hashtable2['mellow'] = ["3", "4", "5"];
    
            $.ajax({
                type: "POST",
                url: '@Url.Action("PerformMagic")',
                dataType: 'json',
                processData: false,
                data: buildParams('theValues', hashtable2),
                success: function () {
    
                }
            });
    
            e.preventDefault();
        });
    });
    

    这个原型实现中有趣的部分是它使用POST,它使用jQuery ajax而不是$ .get或$ .post快捷方式,因为快捷方式不会暴露指定 processData:false 并且使用自定义 buildParams 函数构建请求参数,而不是通过$ .param jQuery函数构建。

答案 1 :(得分:1)

您希望控制器看起来像什么?你可以像这样分解它:

public ActionResult PerformMagic(string[] screaming, string[] mellow) { }

$.get('@Url.Action("PerformMagic")', { screaming: hashtable.screaming, mellow: hashtable.mellow }

或者如果您希望传递string[][],这可能会有效

var hashtable = [];
hashtable.push(["1", "2"]);
hashtable.push(["3", "4", "5"]);

$.get('@Url.Action("PerformMagic")', { arrayOfArrays: hashtable }