Ok, third-time lucky I guess?
(I think this'll be my last implementation sorry Jim - you'll have to work the rest out for yourself, I think I've given you more than enough free pointers for now... if you want more you can contact me and I'll charge you to write it! :P).
This version uses a cookie-based interchange, accepts the input strings (assuming they are filenames) from the javascript, stores these in the instance class along with the token as key, then assembles the ZipFile in-memory (without writing to disk), and then returns the zipfile as a Content Result. For efficiency you could remove the actual token checks against the GUID list and just check against the key in the file list. Obviously you probably won't want the filenames hard-coded in that javascript as I've done, but you can work that part out for yourself.
Hint: Create a database table with identifier/filepath pairs and use the identifiers to lookup the individual file paths after the request is sent to the server...
View Part (I added mine to index.cshtml):
<script type="text/javascript">
function sendStringandGetFiles() {
var files = ['c:\\temp\\afile.txt', 'c:\\temp\\afile2.txt', 'c:\\temp\\afile3.txt'];
$.ajax({
type: "POST",
url: "/Home/GetFile",
contentType: 'application/json',
data: JSON.stringify(files),
success: function (result) {
//alert("Yes This worked! - " + result);
window.location = "/Home/GetFile";
}
});
}
</script>
<h5>Just something to click</h5>
<button onclick="sendStringandGetFiles()">Send String and Get Files</button>
Then Controller Part (I used HomeController.cs)
[AcceptVerbs(HttpVerbs.Post)]
public string GetFile(string[] strings)
{
Guid token = Guid.NewGuid();
InMemoryInstances instance = InMemoryInstances.Instance;
instance.addToken(token.ToString());
instance.addFiles(token.ToString(), strings);
HttpCookie cookie = new HttpCookie("CookieToken");
cookie.Value = token.ToString();
this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
return token.ToString();
}
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetFile()
{
InMemoryInstances instance = InMemoryInstances.Instance;
if (this.ControllerContext.HttpContext.Request.Cookies.AllKeys.Contains("CookieToken"))
{
HttpCookie cookie = this.ControllerContext.HttpContext.Request.Cookies["CookieToken"];
if (instance.checkToken(cookie.Value))
{
cookie.Expires = DateTime.Now.AddDays(-1);
this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
MemoryStream ms = new MemoryStream();
string[] filenames = instance.getFiles(cookie.Value);
using (ZipArchive zs = new ZipArchive(ms,ZipArchiveMode.Create, true))
{
for (int i=0;i < filenames.Length; i++)
zs.CreateEntryFromFile(filenames[i], Path.GetFileName(filenames[i]));
}
FileContentResult resultContent = new FileContentResult(ms.ToArray(),"application/zip");
instance.removeFiles(cookie.Value);
resultContent.FileDownloadName = "ARandomlyGeneratedFileNameHere.zip";
return resultContent;
} else
{
return View("Index");
}
}
else
{
return View("Index");
}
}
InMemoryInstances Class:
public class InMemoryInstances
{
private static volatile InMemoryInstances instance;
private static object syncRoot = new Object();
private List<Guid> activeTokens;
private NameValueCollection filesByKeyCollection;
private InMemoryInstances()
{
activeTokens = new List<Guid>();
filesByKeyCollection = new NameValueCollection();
}
public static InMemoryInstances Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new InMemoryInstances();
}
}
return instance;
}
}
public bool checkToken(string token)
{
return activeTokens.Contains(new Guid(token));
}
public string[] getFiles(string token)
{
return filesByKeyCollection.GetValues(token);
}
public bool addFiles(string token, string[] files)
{
for (int i = 0; i < files.Length; i++)
filesByKeyCollection.Add(token, files[i]);
return true;
}
public bool addToken(string token)
{
activeTokens.Add(new Guid(token));
return true;
}
public bool removeFiles(string token)
{
filesByKeyCollection.Remove(token);
return true;
}
public bool removeToken(string token)
{
return activeTokens.Remove(new Guid(token));
}
}
Hope this helps!