c# dynamically rename file upon download request
Asked Answered
S

3

10

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.

Scorify answered 21/6, 2010 at 12:27 Comment(6)
Can you give a little more detail, particularly, how are the files being downloaded to the client?Mccallum
You need to provide a lot more information here. What's downloading the file, and from what? Where does your code fit in?Fustic
You'd need to have a store of the original name.Eidolon
@ Coding Gorilla... hmm, I don't have any concrete solution, I am open for suggestions. I thought to provide him some link which would return the file (location) with original filenameScorify
How is your file stored? Are you retrieving it from a database, or is it stored in the file system?Mccallum
@ Jon Skeet: the downloading file can be of many types (still haven't defined all of them), but there will be for sure zip, rar, pdf, jpg...Scorify
J
11

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

Jacket answered 21/6, 2010 at 12:31 Comment(3)
check the pasted link in answerJacket
@ile: That doesn't matter. You could use: Response.BinaryWrite(fileContent); aferwards. You must call Response.AppendHeader before you write anything Response or else it won't work. And you should also set the mime-type first: Response.ContentType="text/html";Emery
Ok, thanks, I'll give it a try. Btw, it doesn't matter if the file is stored in DB or in the file system? (my case is file system)Scorify
R
2

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();
}
Redemptioner answered 26/7, 2016 at 18:54 Comment(1)
Please add some comments desribing what your code does; and please use English. Best regards.Cuirass
V
0

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;
    }
Vickey answered 8/1, 2021 at 13:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.