Передача хэш-таблицы {} из JavaScript в контроллер MVC3? - PullRequest
1 голос
/ 10 декабря 2011

Как я могу передать следующее обратно в контроллер 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 ]

3 голосов
/ 12 декабря 2011

Если вы хотите передать значение хеш-таблицы в действие, наиболее естественным способом было бы передать его как словарь для действия

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

При передаче значений с использованием функциональности jQuery Ajax в действие ASP.NET MVC вы сталкиваетесь с большим недоразумением в структуре. ASP.NET MVC ModelBinder ожидает значения, которые должны быть связаны со словарем в теле запроса или URL-адресом с использованием этой схемы именования

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

В этом блоге дается дополнительная информация о схеме именования словарей и списков в 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

В обоих примерах я опустил '&' и разделил значения запроса на отдельные строки для лучшей читаемости.

Так что, если вы хотите передать значения в виде словаря методу действия, вам нужно заставить JQuery и ASP.NET MVC Model Binders говорить. Я могу придумать два варианта:

  1. Изменение схемы именования, которую ASP.NET MVC ожидает для запроса. Параметры
  2. Измените схему именования, которую использует jQuery для сборки параметры запроса

Метод 1 потребует, чтобы вы написали свой собственный связыватель модели, и поскольку функция именования для привязки к аргументам действия словаря где-то скрыта во внутреннем методе UpdateDictionary , написание собственного связывателя модели подразумевает копирование много кода ASP.NET MVC DefaultModelBinder ...

Метод 2 должен быть довольно простым для реализации, потому что jQuery использует функцию param для построения параметров запроса, а функция jQuery ajax позволяет просто передавать необработанные значения, которые были преобразованы пользовательская функция для запроса параметров. Более подробную информацию о функции jQuery ajax можно найти здесь . Смотрите раздел 'processData'.

Я дам прототип реализации jQuery для передачи хеш-таблицы 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 голос
/ 10 декабря 2011

Как вы хотите, чтобы ваш контроллер выглядел?Вы можете разбить его так:

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 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...