I have an ASP.NET WebAPI
project where I need to generate XLS or PDF's depending on the client (jQuery
) request.
Because it's not possible to download a file using $.ajax
, the approach is pretty simple:
- I will request via
$.ajax
the generation of the file (XLS or PDF) on server.but instead of sending the response from server to the client I will save the file locally. The filename will be: some_token.xls. The token should be unique. Maybe a GUID.
- After the file is generated and saved on server, the method will response with a
200 status
and the token just generated (that actually is the filename). - My
jQuery
ajax request method will enter intosuccess function
and then will append the "src" property of an IFrame with the path and token of the just generated file. - The server will download the file and will delete it.
$.ajax({
// the url used to generate the file and save it on server
url: '/api/requestfile',
contentType: "application/json; charset=utf-8",
data: myData,
dataType: "json",
cache: false,
type: 'POST',
success: function (data) {
if (data) {
// if the file was created successfuly on server then download the file
var iframe = $("<iframe/>").attr({
src: 'api/downloadfile/' + data.filetoken, // filetoken generated in server
style: "visibility:hidden;display:none"
}).appendTo(buttonToDownloadFile);
} else {
alert('Something went wrong');
}
}
})
So I have several questions:
a) Where is the right server path to save the file that I will generate? (AppData, customFolder..?
b) Is there any best practice to create tokens as file names or just using a GUID is fine?
c) How can I delete the file in server once it's downloaded? The file won't be accessed by any other user because the file is created by request. So it's a one time file.
UPDATED SOLUTION:
a) The solution was to create a "TempFiles" directory inside App_Data folder that is used to store data.
b) I create a random function to generate a token:
public static string GetRandomToken(int length) {
int intZero = '0';
int intNine = '9';
int intA = 'A';
int intZ = 'Z';
int intCount = 0;
int intRandomNumber = 0;
string strDownloadToken = "";
Random objRandom = new Random(System.DateTime.Now.Millisecond);
while (intCount < length) {
intRandomNumber = objRandom.Next(intZero, intZ);
if (((intRandomNumber >= intZero) &&
(intRandomNumber <= intNine) ||
(intRandomNumber >= intA) && (intRandomNumber <= intZ))) {
strDownloadToken = strDownloadToken + (char) intRandomNumber;
intCount++;
}
}
return strDownloadToken;
}
c) Because I'm using WebAPI the delete is a little bit different. I had to create a Filter:
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) {
// here I added the code to delete the file.
// this Filter is executed after the file response have been sent to server so its safe now to delete the file
}