c# dynamically rename file upon download request
Is it possible to rename file when trying to download it? For example, I would like to store files to folders using their id's but when user downloads file I开发者_运维技巧'd like to return the original filename.
just change name of file over here
Response.AppendHeader("Content-Disposition","attachment; filename=LeftCorner.jpg");
for example
string filename = "orignal file name.ext";
Response.AppendHeader("Content-Disposition","attachment; filename="+ filename +"");
Downloading a File with a Save As Dialog in ASP.NET
nombre = nombre del archivo + extension (ejemplo.txt)
public void DownloadFile(string ubicacion, string nombre)
{
Response.Clear();
Response.ContentType = @"application\octet-stream";
System.IO.FileInfo file = new System.IO.FileInfo(ubicacion);
Response.AddHeader("Content-Disposition", "attachment; filename=" + nombre);
Response.AddHeader("Content-Length", file.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.WriteFile(file.FullName);
Response.Flush();
}
I am working with an API controller in C# and the return of my request needed to be IHttpActionResult
After several research hours, here is my solution.
As a return for my request, I'm using Content
method from ApiController.cs :
protected internal FormattedContentResult<T> Content<T>(HttpStatusCode statusCode, T value, MediaTypeFormatter formatter);
I had to create a custom MediaTypeFormatter which is :
class PdfMediaTypeFormatter : BufferedMediaTypeFormatter
{
private const string ContentType = "application/pdf";
private string FileName { get; set; }
public PdfMediaTypeFormatter(byte[] doc)
{
FileName = $"{DocumentsUtils.GetHeader(doc)}.pdf";
SupportedMediaTypes.Add(new MediaTypeHeaderValue(ContentType));
}
public override bool CanReadType(Type type)
{
return type.IsAssignableFrom(typeof(byte[]));
}
public override bool CanWriteType(Type type)
{
return type.IsAssignableFrom(typeof(byte[]));
}
public override void WriteToStream(Type type, object value, Stream writeStream, HttpContent content)
{
byte[] doc = (byte[])value;
using (Stream ms = new MemoryStream())
{
byte[] buffer = doc;
ms.Position = 0;
ms.Read(buffer, 0, buffer.Length);
writeStream.Write(buffer, 0, buffer.Length);
}
}
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
headers.ContentType = new MediaTypeHeaderValue(ContentType);
headers.ContentDisposition = new ContentDispositionHeaderValue("inline");
headers.ContentDisposition.FileName = FileName;
}
}
And the method in the controller looks like this :
public IHttpActionResult GetDownloadedDocument([FromUri] [FromUri] string IdDocument)
{
byte[] document = service.GetDoc(IdDocument);
return Content(HttpStatusCode.OK, document, new PdfMediaTypeFormatter(document));
}
For the explanation, this ables to override the default behavior of ApiController when it has to return an HttpRequest, as you can see you are able to change what is written is the returned stream, besides you're able to change content disposition, where you set the file name.
Finally, in the constructor of this custom MediaTypeFormatter, I retrieve the Title of the document using a method in a static utils class, which is :
public static string GetHeader(byte[] src)
{
if (src.Length > 0)
using (PdfReader reader = new PdfReader(src))
{
using (MemoryStream ms = new MemoryStream())
{
using (PdfStamper stamper = new PdfStamper(reader, ms))
{
Dictionary<string, string> info = reader.Info;
if (!info.Keys.Contains("Title"))
return null;
else
return info["Title"];
}
}
}
else
return null;
}
精彩评论