将对象列表传递给控制器​​(C#MVC)

时间:2018-06-26 16:47:28

标签: c# jquery json asp.net-mvc file

我的下一个控制器带有参数: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”参数上。 它到达“ null”,就像下一张图片一样:

Capture

我在做什么错?我尝试了不同的方式,但是它不起作用(我放了HttpPost,使用了stringify等)

谢谢!

2 个答案:

答案 0 :(得分:0)

我认为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());

答案 1 :(得分:0)

MVC无法正确绑定 listaFiltrosSeleccionados 参数,因为jQuery以一种方式序列化对象数组,而ASP.NET MVC希望以另一种方式序列化对象。

jQuery这样序列化:listaFiltrosSeleccionados[0][campo]=foo
ASP.NET MVC希望它是:listaFiltrosSeleccionados[0].campo=foo

Here,您可以详细了解此问题。您还可以在其中找到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();
    }});
}

然后您的列表将被更正。