ASP.NET Web API'sinde indirme dosyası adı nasıl ayarlanır


140

ApiController sınıfımda, sunucu tarafından oluşturulan bir dosyayı indirmek için aşağıdaki yöntemi var.

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);
    }
}

Varsayılan indirme dosya adının kimliği olması dışında her şey mükemmel çalışıyor, böylece kullanıcı her seferinde kaydet iletişim kutusunda kendi dosya adını yazmak zorunda kalabilir. Yukarıdaki kodda varsayılan bir dosya adı ayarlamanın bir yolu var mı?


1
Bu yöntemi çağırmak için kullandığınız kodu paylaşabilir misiniz?
Yasser Shaikh

@Yasser - bu bir web API denetleyici yöntemidir - muhtemelen IIS'ye gelen HTTP istekleriyle çağrılır ve bunları ayrıştırır ve yöntemi çağıran yollar ve web API'sini bulur (ve elbette testler tarafından da çağrılır).
Dave Rael

GetMyForm () içinde neler oluyor? Dosyaları bayt akışına mı dönüştürüyorsunuz?
MSIslam

@MSIslam Tür. İşlev, kullanıcının formundan bilgi alır ve ortaya çıkan akışa dönüştürmeden önce bir dosya oluşturur.
Tae-Sung Shin

Yanıtlar:


289

Content-DispositionBaşlığı şuna ayarlamanız gerekir HttpResponseMessage:

HttpResponseMessage response = new HttpResponseMessage();
response.StatusCode = HttpStatusCode.OK;
response.Content = new StreamContent(result);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
    FileName = "foo.txt"
};

21
"Ataşman" tasfiye
sfuqua 30:14

1
Buradan dosya indirmek için başka bir cevabınız var. Eğer kullanmanız fark mu System.Net.Mime.ContentDispositionyoksa ContentDispositionHeaderValue? Biri diğerinden daha güncel ve daha mı tercih ediliyor?
Aydınlık

@Luminous bir cevap ActionResult, biri içinHttpResponseMessage
weston

@weston cevabım sorumu yanıtlamıyor.
Aydınlık

4
@Luminous "Önemli mi?" Ve "Biri diğerinden daha güncel ve daha mı tercih ediliyor?" Hayır, hayır. Biri ActionResultMVC'ler, diğeri WebApi'ler içindir HttpResponseMessage.
weston

27

EDIT: Bir yorumda belirtildiği gibi, Cevabım, gibi kaçması gereken karakterleri açıklamaz ;. Dosya adınız noktalı virgül içeriyorsa Darin tarafından verilen kabul edilen yanıtı kullanmalısınız.

Dosya adını ayarlamak için bir Response.AddHeader ekleyin

Response.AddHeader("Content-Disposition", "attachment; filename=*FILE_NAME*");

Sadece FILE_NAME dosyasını dosyanın adıyla değiştirin.


2
Bu, soru askerine benzer bir problemi çözmede bana yardımcı oldu. Benim durumumda, IE8 bana her zaman söz konusu dosya türünü açma seçeneği verecek şekilde "ek" i "satır içi" olarak değiştirmeyi yararlı buldum.
Scott

2
Kaçmayı kapsamaz. Dosya adı ;özel bir anlama sahip bir şey içeriyorsa ne olur ?
Sam

Sam, Bu cevabı 3 yıl önce yazdığım sırada kaçmanın üstesinden gelmek için gereken cevabımın farkında değildim. Bunu bana işaret ettiğiniz için teşekkür ederim, cevabımda kaçmanın hesaba katılmadığını açıklayan bir düzenleme yaptım. Ama cevabımı aynı tutmak insanlara yardımcı olmuş gibi görünüyordu.
KingPancake

8

Dosya adının doğru şekilde kodlandığından emin olmak, ancak WebApi HttpResponseMessage'dan kaçınmak istiyorsanız aşağıdakileri kullanabilirsiniz:

Response.AddHeader("Content-Disposition", new System.Net.Mime.ContentDisposition("attachment") { FileName = "foo.txt" }.ToString());

ContentDisposition veya ContentDispositionHeaderValue değerlerini kullanabilirsiniz. Her ikisinin bir örneğinde ToString çağrısı sizin için dosya adlarının kodlamasını yapar.


6

Bunun size yardımcı olabileceğini düşünüyorum.

Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName)

4
Kaçmayı kapsamaz. Dosya adı ;özel bir anlama sahip bir şey içeriyorsa ne olur ?
Sam

3

Yanıt için içerik düzenleme başlığını eklemeniz gerekir:

 response.StatusCode = HttpStatusCode.OK;
 response.Content = new StreamContent(result);
 response.AppendHeader("content-disposition", "attachment; filename=" + fileName);
 return response;

3
Kaçmayı kapsamaz. Dosya adı ;özel bir anlama sahip bir şey içeriyorsa ne olur ?
Sam

3

ASP.NET Core MVC kullanıyorsanız, yukarıdaki yanıtlar çok az değişmiştir ...

(Hangi döndürür async Task<JsonResult>) benim eylem yöntemi satır (dönüş deyimi önce herhangi bir yerde) ekleyin:

Response.Headers.Add("Content-Disposition", $"attachment; filename={myFileName}");

Kaçmayı kapsamaz. Dosya adında bir; ya da özel bir anlamı olan başka bir şey mi?
KoalaBear

2

Bu şunları yapmalıdır:

Response.AddHeader("Content-Disposition", "attachment;filename="+ YourFilename)

2
Kaçmayı kapsamaz. Dosya adı ;özel bir anlama sahip bir şey içeriyorsa ne olur ?
Sam

0

Not: Son satır zorunludur.

Access-Control-Expose-Headers'ı belirtmediysek , Kullanıcı Adında Dosya Adı almayacağız.

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");

0

Önceki cevaplar göz önüne alındığında, küreselleştirilmiş karakterlere dikkat etmek gerekir.

Dosyanın adını varsayalım: " Esdrújula prenda ñame - güena.jpg "

İndirmek için ham sonuç: "Esdrújula prenda à ± ame - güena.jpg" [Çirkin]

İndirmek için HtmlEncode sonucu : "Esdr & _250; jula prenda & _241; ame - g & _252; ena.jpg" [Çirkin]

İndirmek için UrlEncode sonucu : " Esdrújula + prenda + ñame + - + güena.jpg " [Tamam]

Ardından, neredeyse her zaman dosya adı üzerinde UrlEncode'u kullanmanız gerekir . Ayrıca, içerik düzenleme başlığını doğrudan dize olarak ayarlarsanız, tarayıcı uyumluluk sorunlarından kaçınmak için surround'ları tırnak işaretleri ile sağlamanız gerekir .

Response.AddHeader("Content-Disposition", $"attachment; filename=\"{HttpUtility.UrlEncode(YourFilename)}\"");

veya sınıf yardımı ile:

var cd = new ContentDisposition("attachment") { FileName = HttpUtility.UrlEncode(resultFileName) };
Response.AddHeader("Content-Disposition", cd.ToString());

System.Net.Mime. ContentDisposition sınıfı alıntılarla ilgilenir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.