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.
![](/-/media/images/corporate/blog/2017/01/1--adding-ribbon-item-to-core.ashx?h=686&w=820&la=en&hash=AC7EDA9CC7DA04E1A5314AC30263055212713E7F)
-
Add a patch file that defines that command, using the class and assembly names.
![](/-/media/images/corporate/blog/2017/01/2--configuration-patch.ashx?la=en&hash=1F848074FC7C1EC36E3DAFB3169125DBCBEF019F)
-
Write a class to implement the command call.
![](/-/media/images/corporate/blog/2017/01/3-command-implementation.ashx?la=en&hash=49210E944E614B62AEF564B7B04E3CEEE349A6B6)
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.