File download issue with Sitecore MVC and resolution

The problem:

while working on the requirement of downloading calendar item(.ics) for an event on the site, I struck with the below given error.

OutputStream is not available when a custom TextWriter is used.

OutputStream is not available when a custom TextWriter is used.
Sitecore MVC error for File as ActionResult for post action

 

Steps to reproduce issue/problem

  1. Using Sitecore MVC form to do the form posting
 @using (Html.BeginRouteForm(Sitecore.Mvc.Configuration.MvcSettings.SitecoreRouteName, FormMethod.Post))
 {
     @Html.Sitecore().FormHandler("SeminarWebinarEvent", "DownloadCalendar")
     @Html.Hidden("eventId", @eventObj.Id.ToString())
     <button type="submit">Add to Calender</button>
 }
  1. Controller Post Action
 [HttpPost]
 public ActionResult DownloadCalendar(string eventId)
 {
     var eventItem = Sitecore.Context.Database.GetItem(new ID(eventId));
     if (eventItem == null)
     {
         //// TODO : Put the code for the error handling
     }

     //// get file stream
     var fileStream = this.eventService.GetCalendarFileStream(eventItem);
     return File(fileStream , "text/calendar", string.Format("{0}.ics", eventItem.Name));
 }
  1. Finally, Click on the Download link of the rendering on the page.

Root Cause

For the fix and the root cause I took the help of the God (not the real almighty but Google ;-)). I found that because of the basic page architecture of Sitecore, the page rendering has already started before the rendering control action returns the file response.

Solution :

After applying couple of different solutions(every time with fingers crossed), I found below given solution much handy and does the job. The solution is much simple and easy to implement.
In this case we need to split the whole action into two different actions like shown in below steps.

  1. Step 1

Put the logic of creating file stream in one action

 [HttpPost]
 public ActionResult DownloadCalendar(string eventId)
     {
          var eventItem = Sitecore.Context.Database.GetItem(new ID(eventId));
          if (eventItem == null)
          {
              //// TODO : Put the code for the error handling
          }

          //// read the file stream in the string format
          var fileStream = this.eventService.GetCalendarFileStream(eventItem);
          //// due to limitation of sitecore MVC redirect to the different action which is responsible for actual download
          return RedirectToAction("ActualCalenderDownload", new { fileString = fileStream, fileName = eventItem["Name"] });
        }
  1. Step 2

At the end of the action redirect to another action which is actually responsible for downloading the file.

  1. Step 3

Create the new action which takes the file stream from above action and returns the fileResult

 [HttpGet]
 public ActionResult ActualCalenderDownload(string fileString, string fileName)
 {
      if (string.IsNullOrWhiteSpace(fileString))
      {
          //// TODO : Put the code for the error handling
      }

      return File(Encoding.UTF8.GetBytes(fileString), "text/calendar", string.Format("{0}.ics", fileName));
 }

Happy Coding 🙂

Sitecore controller rendering action results – what can I return?

Advertisements

Published by

Parag Daraji

Working with Sitecore more than 9 year from now and in total around 13+ years of experience working on Microsoft web technologies stack. Challenges are something which keeps me motivated and moving. I am Sitecore Certified Professional Developer as well as Microsoft Certified Professional Developer. Feel free to hit me up for your Sitecore or web development related queries.

9 thoughts on “File download issue with Sitecore MVC and resolution”

    1. Yeah, even after 6 years working on Sitecore, it still surprise me ….!!! But, I like surprises. Think life without surprises….!!! Thanks for your comment.

  1. HI, I want to embed pdf in the page and for that creating Filestream for PDF and returning the same to the view in MVC web app, it renders on the page directly.

    But while implementing this in sitecore it was not working, i tried your solution but now the file is directly downloading. I don not want direct download, it should display the pdf on page.

    Please help.

  2. I am trying to use this solution but I am still not able to download the pdf it redirects to page not found with controller url in browser

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.