0

I am trying to generate an excel file on my controller from an array of JSON objects. I have only ever passed one JSON object and the same method I used for that doesn't seem to work for Lists or JSON arrays.

AJAX generating object:

    $.ajax({
        type: "GET",
        url: '/home/GetInfoToExportCalgary',
        success: function (data) {
            //console.log(data);
            CalgaryBookingInfo = data;

            for (var i = 0; i < CalgaryBookingInfo.length; i++) {
                if (CalgaryBookingInfo[i].length != 0) {
                    //console.log(CalgaryBookingInfo[i][0].Company + " has bookings")

                    var SumTime = 0;
                    for (var j = 0; j < CalgaryBookingInfo[i].length; j++)
                    {
                        CalgaryNotNullBookings.push({
                            Company: CalgaryBookingInfo[i][j].Company,
                            Location: CalgaryBookingInfo[i][j].Location,
                            PaidHours: CalgaryBookingInfo[i][j].HoursPaid,
                            Start: CalgaryBookingInfo[i][j].Start,
                            End: CalgaryBookingInfo[i][j].End,
                            Time: CalgaryBookingInfo[i][j].Time,
                            Total: SumTime + CalgaryBookingInfo[i][j].Time
                        });
                        SumTime += CalgaryBookingInfo[i][j].Time;
                    }

                    CalgaryNotNullBookings.push({
                        Company: "",
                        Location: "",
                        PaidHours: "",
                        Start: "",
                        End: "",
                        Time: "",
                        Total: SumTime
                    });
                }
            }
            console.log(CalgaryNotNullBookings);
            //buildHtmlTable(RetreivedClients);
        }
    })

AJAX Sending Array:

Here I am simply sending a POST with the data that I generated before-hand and called on a button click.

    function ExportCalgary(data) {
        $.ajax({
            type: "POST",
            url: '/home/ExportCalgary',
            data: data,
            success: function (data) {
                console.log("huehuehuehuehueh");
                if (data.status) {
                    //Refresh the calender
                    //location.reload();
                    $('#myModalSave').modal('hide');
                }
            },
            error: function () {
                alert('Failed');
            }
        })
    }

Controller POST function:

[HttpPost]
public JsonResult ExportCalgary(List<ClientBookingInfo> e)
{
    var status = false;

    //string[] columns = { "Company", "Location", "PaidHours", "Start", "End", "Time" , "Total" };
    //byte[] filecontent = ExcelExportHelper.ExportExcel(dataToConvert, "Technology", true, columns);
    //return File(filecontent, ExcelExportHelper.ExcelContentType, "CalgaryClientInfo_" + DateTime.Now.Year+"_" + DateTime.Now.Month + ".xlsx");

    ExcelPackage excel = new ExcelPackage();
    var workSheet = excel.Workbook.Worksheets.Add("Sheet1");
    workSheet.TabColor = System.Drawing.Color.Black;
    workSheet.DefaultRowHeight = 12;
    //Header of table  
    //  
    workSheet.Row(1).Height = 20;
    workSheet.Row(1).Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
    workSheet.Row(1).Style.Font.Bold = true;
    workSheet.Cells[1, 1].Value = "Company";
    workSheet.Cells[1, 2].Value = "Location";
    workSheet.Cells[1, 3].Value = "PaidHours";
    workSheet.Cells[1, 4].Value = "Start";
    workSheet.Cells[1, 5].Value = "End";
    workSheet.Cells[1, 6].Value = "Time";
    workSheet.Cells[1, 7].Value = "Total";
    //Body of table  
    //  
    int recordIndex = 2;
    for(int i = 0; i < e.Count; i++)
    { 
        workSheet.Cells[recordIndex, 1].Value = e[i].Company;
        workSheet.Cells[recordIndex, 2].Value = e[i].Location;
        workSheet.Cells[recordIndex, 3].Value = e[i].PaidHours;
        workSheet.Cells[recordIndex, 4].Value = e[i].Start;
        workSheet.Cells[recordIndex, 5].Value = e[i].End;
        workSheet.Cells[recordIndex, 6].Value = e[i].Time;
        workSheet.Cells[recordIndex, 7].Value = e[i].Total;
        recordIndex++;
    }
    workSheet.Column(1).AutoFit();
    workSheet.Column(2).AutoFit();
    workSheet.Column(3).AutoFit();
    workSheet.Column(4).AutoFit();
    workSheet.Column(5).AutoFit();
    workSheet.Column(6).AutoFit();
    workSheet.Column(7).AutoFit();
    string excelName = "CalgaryClientInfo_" + DateTime.Now.Year+"_" + DateTime.Now.Month;
    using (var memoryStream = new MemoryStream())
    {
        Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        Response.AddHeader("content-disposition", "attachment; filename=" + excelName + ".xlsx");
        excel.SaveAs(memoryStream);
        memoryStream.WriteTo(Response.OutputStream);
        Response.Flush();
        Response.End();

        status = true;
    }



    return new JsonResult { Data = new { status = status } };
}

Currently when I debug, the List "ClientBookingInfo e" returns NULL and Im not sure what could be going wrong. Could it be something with the encoding or data type of the JSON? Am I missing some lines which specify that the JSON I am sending is going to be an array ?

Also here is the class ClientBookingInfo:

public class ClientBookingInfo
{
    public string Company { get; set; }
    public string Location { get; set; }
    public int PaidHours { get; set; }
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public int Time { get; set; }
    public double Total { get; set; }
}

Thanks in advance! :)

9
  • What is in data parameter when you call the ExportCalgary method ? Are you returning a file from your action method ? Are trying to do a file download via ajax ? Do not try file download via ajax. Do a normal form submit Commented Feb 3, 2018 at 23:27
  • For the ajax call to work (model binding), you should send the stringified version of the array along with application/json as contentType(data: JSON.stringify(data), contentType: "application/json",) Commented Feb 3, 2018 at 23:29
  • The data I am passing to the method is the CalgaryNotNullBookings[] array I push to in the earlier ajax call. Commented Feb 4, 2018 at 0:05
  • I am just trying to send the data to my controller which will then generate the excel file for downloading Commented Feb 4, 2018 at 0:06
  • @Shyju I tried that and the list is still null on my controller when i debug :( Commented Feb 4, 2018 at 0:07

1 Answer 1

1

When posting complex data , you should send the JSON stringified version of your object(s) while specifying contentType as application/json

You can use the JSON.stringify method to convert your array to it's corresponding json string.

var data = [];
data.push({ Company: "Microsoft", Location: "Redmond" , Total:123 });
data.push({ Company: "UrbanScience", Location:"Detroit", Total:456 });

$.ajax({
    type: "POST",
    url: '@Url.Action("ExportCalgary")',
    data: JSON.stringify(data),
    contentType: "application/json",
    success: function(data) {
        console.log("data :", data);
        // Do something with the response
    },
    error: function() {
        alert('Failed');
    }
});

Now model binder will be able to properly bind the data from your ajax request and you will not get null in your action method parameter.

On a side note, downloading a file via ajax might not work. Consider doing a normal (non-ajax) form submit to your action method which can return a file. Also if the data needed for building your file is available in the server code (let's say it is in a db table which you can read from), i suggest you sending the minimum data needed (like a uniqueId ) to server and have the server read the data and using this Id and use that to return the file.

If you can pass an id to your action method which can return a file, you can call it from javascript using window.open method.

window.open("/Documents/Download?id=2");

Or setting the current url to the download url

window.location.href = "/Documents/Download?id=2";

Assuming you have a Download action method which takes an id parameter and return a file.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the tips :) and help with the sending problem!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.