We have a custom table of data which users may wish to download as a CSV so I thought the best thing to do would be to create a razor script that runs on an otherwise empty template and generates a CSV. This is all working except that at the end of my CSV, I'm getting trace code. The trace says there's an error (yet the CSV exists above the trace in full). The error is that the "Thread was being aborted" which, according to someone on StackOverflow can happen when Response.End() is called. The suggestion was to change Response.End() to Response.Flush() and ApplicationInstance.CompleteRequest(). However, when I do that, I get a Server Error appended to my CSV saying that the "Server cannot append header after HTTP headers have been sent".
Does anyone have any ideas? My template and razor are below:
I'd recommend putting this into a base RestExtension, but to answer your question, I'm guessing that the call to Response.End() is interfering with the rest of what Umbraco is trying to do when it is executing the macro. I would suggest replacing the whole use of a stream writer and simply doing a Response.Write().
Generating a CSV dynamically via Razor
We have a custom table of data which users may wish to download as a CSV so I thought the best thing to do would be to create a razor script that runs on an otherwise empty template and generates a CSV. This is all working except that at the end of my CSV, I'm getting trace code. The trace says there's an error (yet the CSV exists above the trace in full). The error is that the "Thread was being aborted" which, according to someone on StackOverflow can happen when Response.End() is called. The suggestion was to change Response.End() to Response.Flush() and ApplicationInstance.CompleteRequest(). However, when I do that, I get a Server Error appended to my CSV saying that the "Server cannot append header after HTTP headers have been sent".
Does anyone have any ideas? My template and razor are below:
<%@ Master Language="C#" MasterPageFile="~/umbraco/masterpages/default.master" AutoEventWireup="true" %><asp:Content ContentPlaceHolderID="ContentPlaceHolderDefault" runat="server"><umbraco:Macro Alias="GenerateCSV" runat="server" /></asp:Content>
@using umbraco.MacroEngines;
@using umbraco.cms.businesslogic.member;
@using AHL.BO;
@using System.Text;
@using System.IO;
@using System.Threading;
@{
int pItemID = 0;
int.TryParse(Request.QueryString["id"], out pItemID);
if (pItemID == 0)
{
Response.Redirect("~/");
}
var member = Member.GetCurrentMember();
PItem pItem = new PItem(pItemID, member.Id);
StringWriter sw = new StringWriter();
sw.WriteLine("\"Name:\",\"" + pItem.Name + "\"");
sw.WriteLine("\"Description:\",\"" + pItem.Description + "\"");
sw.WriteLine("\"Last modified:\",\"" + pItem.DateModifiedString + "\"" + Environment.NewLine + Environment.NewLine);
sw.WriteLine("\"Title\",\"Description\"");
foreach (var item in Model.NodesById(pItem.MusicItems))
{
sw.WriteLine("\"" + item.title + "\",\"" + item.descriptionSentence + "\"");
}
Response.ContentType = "text/csv";
Response.AddHeader("content-disposition", "attachment;filename=" + string.Format("test-{0}.csv",string.Format("{0:ddMMyyyy}",DateTime.Today)));
Response.Clear();
using (StreamWriter writer = new StreamWriter(Response.OutputStream, Encoding.UTF8))
{
writer.Write(sw.ToString());
}
Response.End();
}
I'd recommend putting this into a base RestExtension, but to answer your question, I'm guessing that the call to Response.End() is interfering with the rest of what Umbraco is trying to do when it is executing the macro. I would suggest replacing the whole use of a stream writer and simply doing a Response.Write().
Did you get it figured out eventually?
is working on a reply...