Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Alex Wilks 27 posts 56 karma points
    Oct 10, 2012 @ 13:11
    Alex Wilks
    0

    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(pItemIDmember.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.OutputStreamEncoding.UTF8))
      {
          writer.Write(sw.ToString());
      }
      Response.End();
    }

  • Douglas Ludlow 210 posts 366 karma points
    Oct 10, 2012 @ 19:28
    Douglas Ludlow
    0

    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().

    @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.Write(sw.ToString());
    }
  • Douglas Ludlow 210 posts 366 karma points
    Oct 26, 2012 @ 01:38
    Douglas Ludlow
    0

    Did you get it figured out eventually?

Please Sign in or register to post replies

Write your reply to:

Draft