Dans ma classe ApiController, j’ai utilisé la méthode suivante pour télécharger un fichier créé par le serveur.
public HttpResponseMessage Get(int id)
{
try
{
string dir = HttpContext.Current.Server.MapPath("~"); //location of the template file
Stream file = new MemoryStream();
Stream result = _service.GetMyForm(id, dir, file);
if (result == null)
{
return Request.CreateResponse(HttpStatusCode.NotFound);
}
result.Position = 0;
HttpResponseMessage response = new HttpResponseMessage();
response.StatusCode = HttpStatusCode.OK;
response.Content = new StreamContent(result);
return response;
}
catch (IOException)
{
return Request.CreateResponse(HttpStatusCode.InternalServerError);
}
}
Tout fonctionne parfaitement, sauf que le nom de fichier à télécharger par défaut est son identifiant. Il est donc possible que l'utilisateur doive taper son propre nom de fichier lors de l'enregistrement en tant que dialogue à chaque fois. Est-il possible de définir un nom de fichier par défaut dans le code ci-dessus?
Vous devez définir l'en-tête Content-Disposition
sur le HttpResponseMessage
:
HttpResponseMessage response = new HttpResponseMessage();
response.StatusCode = HttpStatusCode.OK;
response.Content = new StreamContent(result);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "foo.txt"
};
EDIT: Comme mentionné dans un commentaire, ma réponse ne prend pas en compte les caractères qui doivent être échappés comme un ;
. Vous devez utiliser la réponse acceptée par Darin si votre nom de fichier peut contenir un point-virgule.
Ajouter un Response.AddHeader pour définir le nom de fichier
Response.AddHeader("Content-Disposition", "attachment; filename=*FILE_NAME*");
Il suffit de remplacer FILE_NAME par le nom du fichier.
Si vous souhaitez vous assurer que le nom du fichier est correctement codé tout en évitant WebApi HttpResponseMessage, vous pouvez utiliser les éléments suivants:
Response.AddHeader("Content-Disposition", new System.Net.Mime.ContentDisposition("attachment") { FileName = "foo.txt" }.ToString());
Vous pouvez utiliser ContentDisposition ou ContentDispositionHeaderValue. Appeler ToString sur une instance de l’un ou l’autre fera l’encodage des noms de fichiers pour vous.
Je pense que cela pourrait vous être utile.
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName)
Si vous utilisez ASP.NET Core MVC, les réponses ci-dessus sont légèrement modifiées ...
Dans ma méthode d'action (qui retourne async Task<JsonResult>
), j'ajoute la ligne (n'importe où avant l'instruction return):
Response.Headers.Add("Content-Disposition", $"attachment; filename={myFileName}");
Vous devez ajouter l'en-tête content-disposition à la réponse:
response.StatusCode = HttpStatusCode.OK;
response.Content = new StreamContent(result);
response.AppendHeader("content-disposition", "attachment; filename=" + fileName);
return response;
Cela devrait faire:
Response.AddHeader("Content-Disposition", "attachment;filename="+ YourFilename)
Remarque: la dernière ligne est obligatoire.
Si nous ne spécifions pas Access-Control-Expose-Headers , nous n'obtiendrons pas le nom du fichier dans l'interface utilisateur.
FileInfo file = new FileInfo(FILEPATH);
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = file.Name
};
response.Content.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");