Отправка данных на сервер с помощью fnServerParams и aoData для jquery DataTable не работает в MVC4

Я хочу отправить дополнительные данные на сервер (ASP.Net MVC4) для моей таблицы данных jquery. Есть много примеров того, как работать на стороне клиента, но я не могу заставить его работать на стороне сервера.

Вот код:

JavaScript:

$(document).ready(function () {    
    var oTable = $('#myDataTable').dataTable({
        "bServerSide": true,
        "sAjaxSource": "SearchPatient/DataHandler",        
        "fnServerParams": function (aoData) {
            alert('in fnServerParams');
            aoData.push( { "name": "more_data", "value": "my_value" } );
        }

    });
});

Примечание: оповещение срабатывает, значит, сама функция работает.

Мой модельный класс:

    /// <summary>
    /// Class that encapsulates most common parameters sent by DataTables plugin
    /// </summary>
    public class JQueryDataTableParamModel
    {
        /// <summary>
        /// fnServerparams, this should be an array of objects?
        /// </summary>        
        public object[] aoData { get; set; }

        /// <summary>
        /// Request sequence number sent by DataTable, same value must be returned in response
        /// </summary>       
        public string sEcho { get; set; }

        /// <summary>
        /// Text used for filtering
        /// </summary>
        public string sSearch { get; set; }

        /// <summary>
        /// Number of records that should be shown in table
        /// </summary>
        public int iDisplayLength { get; set; }

        /// <summary>
        /// First record that should be shown(used for paging)
        /// </summary>
        public int iDisplayStart { get; set; }

        /// <summary>
        /// Number of columns in table
        /// </summary>
        public int iColumns { get; set; }

        /// <summary>
        /// Number of columns that are used in sorting
        /// </summary>
        public int iSortingCols { get; set; }

        /// <summary>
        /// Comma separated list of column names
        /// </summary>
        public string sColumns { get; set; }

        /// <summary>
        /// Text used for filtering
        /// </summary>
        public string oSearch { get; set; }

    }

и, наконец, мой контроллер:

   public ActionResult DataHandler(JQueryDataTableParamModel param)
    {
        if (param.aoData != null)
        {
            // Get first element of aoData.  NOT working, always null              
            string lSearchValue = param.aoData[0].ToString();

            // Process search value
            // ....
        }


        return Json(new
        {                
            sEcho = param.sEcho,
            iTotalRecords = 97,
            iTotalDisplayRecords = 3,
            aaData = new List<string[]>() {
                new string[] {"1", "IE", "Redmond", "USA", "NL"},
                new string[] {"2", "Google", "Mountain View", "USA", "NL"},
                new string[] {"3", "Gowi", "Pancevo", "Serbia", "NL"}
                }
        },
        JsonRequestBehavior.AllowGet);
    }

Примечание: обработчик действия срабатывает, поэтому вызов ajax для получения данных также работает, и моя таблица данных заполняется тремя строками.

Проблема в том, что aoData всегда равен нулю. Я ожидаю, что первый элемент будет содержать «my_value».

Любая помощь высоко ценится!


person user1386636    schedule 03.12.2013    source источник


Ответы (3)


После нескольких часов поиска ответа, наконец, разместил его здесь. Только чтобы придумать ответ в считанные минуты:

Это делает трюк:

Добавьте эту строку на стороне сервера в DataHandler:

var wantedValue = Request["more_data"];

Таким образом, значение находится в запросе, а не в модели.

Спасибо.

person user1386636    schedule 03.12.2013

Значения действительно есть в модели, но они передаются как отдельные поля, а не как элементы aoData:

public class JQueryDataTableParamModel {
    /// The "more_data" field specified in aoData
    public string more_data { get; set; }

    public string sEcho { get; set; }
    public string sSearch { get; set; }
    public int    iDisplayLength { get; set; }
    public int    iDisplayStart { get; set; }
    public int    iColumns { get; set; }
    public int    iSortingCols { get; set; }
    public string sColumns { get; set; }
    public string oSearch { get; set; }
}

Применение:

public ActionResult DataHandler(JQueryDataTableParamModel param) {
    /// Reference the field by name, not as a member of aoData
    string lSearchValue = param.more_data;

    return Json( 
        new {                
            sEcho = param.sEcho,
            iTotalRecords = 97,
            iTotalDisplayRecords = 3,
            aaData = new List<string[]>() {
                new string[] {"1", "IE", "Redmond", "USA", "NL"},
                new string[] {"2", "Google", "Mountain View", "USA", "NL"},
                new string[] {"3", "Gowi", "Pancevo", "Serbia", "NL"}
            }
        },
        JsonRequestBehavior.AllowGet
    );
}
person SetFreeByTruth    schedule 09.01.2014

Я опубликую еще один ответ, чтобы показать способ избежать дублирования кода.

Вы также можете сделать свой JQueryDataTableParamModel базовым классом для других. Datatables будет отправлять пользовательские данные в тот же объект, поэтому вы не можете заставить модель связывать их напрямую, если ваша модель представления C# точно не соответствует отправленному объекту DataTables.

Этого можно достичь, как ответил @SetFreeByTruth, но у вас может быть некоторое дублирование кода, если вы хотите, чтобы он использовался во всем проекте. В этой таблице есть more_data, что, если у вас есть другая таблица только со свойством custom_data? Вам нужно будет заполнить свой объект несколькими полями или создать несколько моделей представления данных, каждая с вашими пользовательскими данными.

Для вашего сценария вы можете использовать наследование. Создайте новый класс следующим образом:

//Inheritance from the model will avoid duplicate code
public class SpecificNewParamModel: JQueryDataTableParamModel
{
    public string more_data { get; set; }
}

Используя это так в контроллере:

public JsonResult ReportJson(SpecificNewParamModel Model)
{
    //code omitted code for clarity
    return Json(Return);
}

Если вы отправите запрос DataTables и просмотрите Model, вы увидите, что он заполнен вашими пользовательскими данными (more_data) и обычными данными DataTables.

person diego.dona    schedule 14.01.2016