Reputation: 7
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:
What am I doing wrong? I tried differents way but it doesn't work (I put HttpPost, used stringify, etc.)
Thanks!
Upvotes: 0
Views: 1411
Reputation: 382
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.
Upvotes: 0
Reputation: 196
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());
Upvotes: 1