I have the following code on the client side for retrieving data from the HTML Table and then send it to the server through the page method:
function dtExportToCSV(dataTable) {
var elements = dtDataToJSON(dataTable);
var headers = dtHeadersToJSON(tableSelector);
jQuery.ajax({
type: "POST",
url: "Report.aspx/exportToCSV",
data: "{'elements': " + elements + ", 'headers': " + JSON.stringify(headers) + "}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
if (msg.d) {
} else {
}
},
error: function(xhr, ajaxOptions, thrownError) {
alert(xhr.statusText);
}
});
}
Then I use the following code on the server side, to export the retrieved data to CSV file.
/// <summary>
///
/// </summary>
/// <param name="elements"></param>
/// <param name="headers"></param>
[WebMethod(EnableSession=true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static bool exportToCSV(List<object> elements, List<string> headers)
{
try
{
string attachmentType = "attachment; filename=ShortageReport.csv";
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.AddHeader("content-disposition", attachmentType);
HttpContext.Current.Response.ContentType = "text/csv";
HttpContext.Current.Response.AddHeader("Pragma", "public");
writeHeadersInfo(headers);
HttpContext.Current.Response.End();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return false;
}
But I get this expcetion: Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.
Does anyone knows how to handle this issue?
Any help would be highly appreciated! Thanks in Advance!
~ Eder Quiñones
I kind of did what Leon suggested as an answer, but instead I used generic handler.
1.- Retrieve data from the client, build json & send data to the server (Main Page):
function dtExportToCSV(dataTable) {
var elements = dtDataToJSON(dataTable);
var headers = dtHeadersToJSON(tableSelector);
jQuery.ajax({
type: "POST",
url: "ashx/Export.ashx",
data: "{'elements': " + elements + ", 'headers': " + headers + "}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
window.open("Export.aspx", "Export CSV", "width=120,height=300");
},
error: function(xhr, ajaxOptions, thrownError) {
alert(xhr);
}
});
return false;
}
2.- Initialize the session variable (as StringBuilder) for data inter-exchange via aspx pages (Main Page):
protected void Page_Load(object sender, EventArgs e)
{
if (Session["ExportCSV"] == null)
{
Session["ExportCSV"] = new StringBuilder();
}
if (!IsPostBack)
{
}
}
3.- Build the CSV (Generic Handler):
public class Export : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
object json = null;
byte[] input = null;
JavaScriptSerializer javascriptSerializer = null;
StringBuilder sb = null;
List<object> elementList = null;
List<string> headerList = null;
try
{
input = readToEnd(context.Request.InputStream);
sb = new StringBuilder();
javascriptSerializer = new JavaScriptSerializer();
foreach (byte chr in input)
{
sb.Append((char)chr);
}
json = javascriptSerializer.DeserializeObject(sb.ToString());
elementList = new List<object>();
headerList = new List<string>();
var dictionary = json.toType(new Dictionary<string, object>());
foreach (KeyValuePair<string, object> keyValuePair in dictionary)
{
switch (keyValuePair.Key)
{
case "elements":
case "ELEMENTS":
{
object[] elements = (object[])keyValuePair.Value;
foreach (object element in elements)
{
elementList.Add(element);
}
break;
}
case "headers":
case "HEADERS":
{
object[] headers = (object[])keyValuePair.Value;
foreach (object header in headers)
{
headerList.Add((string)header);
}
break;
}
}
}
((StringBuilder) context.Session["ExportCSV"]).Append(writeBodyInfo(elementList, headerList));
((StringBuilder) context.Session["ExportCSV"]).Append(writeHeadersInfo(headerList));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
}
4.- Show up the save file dialog (Export.aspx):
public partial class Export : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
exportToCSV();
}
}
private void exportToCSV()
{
Context.Response.Clear();
Context.Response.ClearContent();
Context.Response.ClearHeaders();
Context.Response.AddHeader("Content-Disposition", "attachment;filename=ShortageReport.csv");
Context.Response.ContentType = "text/csv";
char[] separator = Environment.NewLine.ToCharArray();
string csv = ((StringBuilder)Session["ExportCSV"]).ToString();
foreach (string line in csv.Split(separator))
{
Context.Response.Write(line);
}
Context.Response.Flush();
Context.Response.End();
}
}
Any improvement, suggestion?
~ Eder Quiñones