Передача списка объектов в контроллер (C # MVC) - PullRequest
0 голосов
/ 26 июня 2018

У меня есть следующий контроллер с параметрами: controlador, mostrarBorrados, listaFiltrosSeleccionados, cantRegistros и reportType.

[HttpGet]
public ActionResult GetReport(string controlador, bool mostrarBorrados, List<FiltroSeleccionado> listaFiltrosSeleccionados, int? cantRegistros, string reportType)
{

    //...

    return File(renderedBytes, mimeType);
}

И я называю это следующим кодом ajax:

$.ajax({
url: '@Url.Action("GetReport", "Report")',
type: 'GET',
dataType: 'binary',
data: { controlador: "condIva", mostrarBorrados: mostrarBorrados,
    listaFiltrosSeleccionados: listaFiltrosSeleccionados, cantRegistros : cantRegistros, reportType: "EXCELOPENXML" },
success: function (response) {
    var url = URL.createObjectURL(response);
    var $a = $('<a />', {
        'href': url,
        'download': 'descarga.xlsx',
        'text': "click"
    }).hide().appendTo("body")[0].click();
}});

Файл создан правильно, но проблема в параметрах "listaFiltrosSeleccionados". Это прибывает "нуль", как следующее изображение:

Capture

Что я делаю не так? Я пробовал другой способ, но он не работает (я поставил HttpPost, использовал stringify и т. Д.)

Спасибо!

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Параметр listaFiltrosSeleccionados не может быть правильно привязан MVC, поскольку jQuery сериализует массив объектов одним способом, а ASP.NET MVC ожидает, что это будет сериализовано другим способом.

jQuery сериализует это так: listaFiltrosSeleccionados[0][campo]=foo
ASP.NET MVC ожидает, что это будет: listaFiltrosSeleccionados[0].campo=foo

Здесь вы можете прочитать об этой проблеме в деталях. Также там вы можете найти патч jQuery, который вносит поддержку точечной нотации в сериализацию jQuery: https://gist.github.com/migimunz/61557b7fab233604ba46

Таким образом, вы можете включить этот патч в свои скрипты и отправить данные на сервер следующим образом:

var mostrarBorrados = true;
var cantRegistros = 1;
var listaFiltrosSeleccionados = [{
    campo: 'foo',
    opcionSeleccionado: 'bar',
    tabla: 't1',
    valor1: 'v1',
    valor2: 'v2'
}, {
    campo: 'abc',
    opcionSeleccionado: 'def',
    tabla: 't2',
    valor1: 'vlr1',
    valor2: 'vlr2'
}];

function buttonClick() {
    $.ajax({
    url: '@Url.Action("GetReport", "Report")',
        type: 'GET',
    dataType: 'binary',
    data: $.param({ controlador: "condIva", mostrarBorrados: mostrarBorrados,
        listaFiltrosSeleccionados: listaFiltrosSeleccionados, cantRegistros : cantRegistros, reportType: "EXCELOPENXML" }, false, true),
    success: function (response) {
        var url = URL.createObjectURL(response);
        var $a = $('<a />', {
            'href': url,
            'download': 'descarga.xlsx',
            'text': "click"
        }).hide().appendTo("body")[0].click();
    }});
}

Тогда ваш список будет связан правильно.

0 голосов
/ 26 июня 2018

Я думаю, что MVC не удалось преобразовать полученные данные в List<FiltroSeleccionado>. Используйте связыватель модели для преобразования данных в вашу модель.

public class FiltroSeleccionadoCollectionModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{

    if (bindingContext == null)
    {
        throw new ArgumentNullException(nameof(bindingContext));
    }

    if (bindingContext.ModelMetadata.ModelType == typeof(DateTime))
    {
        var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        var str = valueProviderResult.AttemptedValue;

        //convert str to List<FiltroSeleccionado> and return it;
    }

    return null;
}

Вы можете изменить метод действия следующим образом:

public ActionResult GetReport(string controlador, 
                              bool mostrarBorrados, 
[ModelBinder(typeof(FiltroSeleccionadoCollectionModelBinder))]List<FiltroSeleccionado>
                              listaFiltrosSeleccionados, 
                              int? cantRegistros,
                              string reportType)
{
//...
}

Или установить следующий код при запуске:

 ModelBinders.Binders.Add(typeof(List<FiltroSeleccionado>), new FiltroSeleccionadoCollectionModelBinder());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...