简体   繁体   中英

Passing object list to controller (C# MVC)

I've the next controller with parameters: controlador, mostrarBorrados, listaFiltrosSeleccionados, cantRegistros and reportType.

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

    //...

    return File(renderedBytes, mimeType);
}

And I call it with the next ajax code:

$.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();
}});

The file is generated correctly, but the problem is with "listaFiltrosSeleccionados" parameters. It arrives "null", like the next image:

Capture

What am I doing wrong? I tried differents way but it doesn't work (I put HttpPost, used stringify, etc.)

Thanks!

I think MVC could not convert receiving data to List<FiltroSeleccionado> . Use model binder to transforming data to your model.

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

You can change your action method as:

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

Or set following code in startup:

 ModelBinders.Binders.Add(typeof(List<FiltroSeleccionado>), new FiltroSeleccionadoCollectionModelBinder());

The listaFiltrosSeleccionados parameter could not be bound by MVC correctly, because jQuery serializes array of objects in one way, while ASP.NET MVC expects this to be serialized in another way.

jQuery serializes this like that: listaFiltrosSeleccionados[0][campo]=foo
ASP.NET MVC expects it to be: listaFiltrosSeleccionados[0].campo=foo

Here you can read about this problem in details. Also there you can find jQuery patch which brings support of dot-notation to jQuery serialization: https://gist.github.com/migimunz/61557b7fab233604ba46

So, you can include this patch in your scripts and send data to server in following way:

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

Then your list will be bound correclty.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM