Code: Download a CSV from within Sitecore User Manager
I had a requirement on a recent project to download a .CSV from within Sitecore User Manager. Basically, it was to download all users within a particular domain into a .csv file. The 'download' bit proved tricky, though.
To add a new button to Sitecore's ribbons, you need to:
-
Add entries in Core (in my case /sitecore/content/Applications/Security/User Manager/Ribbon/Home/ ) for the ribbon section and button. Note that you have to specify a command to be run.
-
Add a patch file that defines that command, using the class and assembly names.
-
Write a class to implement the command call.
All that's fine - but then, in a postback to a Sitecore window, how do you force a file to be downloaded? My usual approach - using the HTTPResponse class for the current control - doesn't work.
Well, I found one suggestion by Alan Coates - "open another window"- and later another by Ishraq Fataftah of "use an iframe" - which would both probably work, but feel ... inelegant. I really don’t like iFrames, and new Windows aren’t ideal. I noticed that the SheerResponse class has a Download() method... but it needs a file path. On Disk. so I'd have to write my file to disk.
Well, isn't that what the Temp folder is for?
Thus, my code became:
// Flush csvStream into MemoryStream 'mem'
csvStream.Flush();
// Generate a file path
string filePath = string.Format("/temp/File {0}.csv", DateTime.Now.ToString("yyyy-MM-dd HHmmssf"));
// Write to disc
byte[] memArr = mem.ToArray();
FileUtil.WriteToFile(filePath, ref memArr );
// Download from disc
SheerResponse.Download(filePath);
This works nicely - the file gets created in Temp, and then downloads to the client thanks to the SheerResponse.Download() call. No iFrames, no new windows.
Oh, bonus note - CSVHelper is brilliant for actually generating CSV files. I just add the Nuget, and away we go.