3

I am using ServiceStack for a simple web application. The main purpose is to let a user download a file. I am using an HttpResult as follows:

public class FileDownloadService : Service
{
 public object Any()
 {
  string fileFullPath = "...";
  string mimeType = "application/pdf";
  FileInfo fi = new FileInfo(fileFullPath);

  byte[] reportBytes = File.ReadAllBytes(fi.FullName);
  result = new HttpResult(reportBytes, mimeType);

  return result;
 }
}

This opens a dialog in the user's browser and the user can specify where to save the file. A default name is specified, which is the name of the restPath of ServiceStack.

My question is: is it possible to specify a custom file name for when the user chooses to save (changing the default one)? I tried to work with HttpResult properties, but no luck. Thanks in advance!

AdrianS
  • 63
  • 5
  • When the user opens the "save as" dialog of the browser, he has a default file name already written, that is the restPath specified in routing file of ServiceStack + file extension (in my case, "downloadFile.pdf", because the service is addressed by the "/downloadFile" rout). I would like to change this default name, for example by changing it to "UserSurname_UserName.pdf". I do not know if it is possible and, if yes, how can I obtain this result... – AdrianS Jul 22 '16 at 12:07

3 Answers3

4

You should set the 'Content-Disposition' header on the HTTP result. That allows to set the filename:

 public object Any()
 {
     string fileFullPath = "...";
     string mimeType = "application/pdf";
     FileInfo fi = new FileInfo(fileFullPath);

     byte[] reportBytes = File.ReadAllBytes(fi.FullName);
     result = new HttpResult(reportBytes, mimeType);

     result.Headers.Add("Content-Disposition", "attachment;filename=YOUR_NAME_HERE.pdf;");    

     return result;
 }
AVee
  • 3,348
  • 17
  • 17
  • Thank you! I was writing my own solution while you were writing yours: I like to see that they are the same! – AdrianS Jul 22 '16 at 14:35
  • You can also just return `new HttpResult(fi, asAttachment:true)` and ServiceStack will [populate the Content-Disposition using info from the FileInfo](https://github.com/ServiceStack/ServiceStack/blob/5021095b8199f45cead3cb3655b8b6e26482927d/src/ServiceStack/HttpResult.cs#L79) automatically. – mythz Jul 22 '16 at 17:49
  • Thank you mythz, you are right and that was my first choice. But when the file was put in a network folder, the things changed, because access to the file was denied, even inserting the HttpResult generation in the same "impersonation-using" I used to read the file (I used the methods in [How do you do Impersonation in .NET](http://stackoverflow.com/questions/125341/how-do-you-do-impersonation-in-net)). So, I had to use impersonation to retrieve the file content before generating a HttpResult. – AdrianS Jul 25 '16 at 09:02
2

I have found the solution. I was deceived by the readonly properties of the HttpResult. In order to change the default file name, I discovered that I have to add the following line, that treats the content-disposition:

result.Headers[HttpHeaders.ContentDisposition] = "attachment; filename=\"UserSurname_UserName.pdf\"";

Thank you all for your time!

AdrianS
  • 63
  • 5
  • You can also just return `new HttpResult(fi, asAttachment:true)` and it will use the automatically add the info from `FileInfo`. – mythz Jul 22 '16 at 22:53
0

If I understood your question correctly, what you want is the user wants to rename the file. This is nothing to do with the server. The user has to do some changes in the brwoser he is uses.

e.g Firefox - Tools > Options > General

Then check the "Always ask me where to save files"

Chrome - Settings > Downloads

Then check the "Ask where to save each file before "

Then it will open file browser where to save, you may change your file name what ever your wanted

Tharsan Sivakumar
  • 6,351
  • 3
  • 19
  • 28