Ошибка Internet Explorer при использовании Asp MVC 4.0 FileResult - PullRequest
3 голосов
/ 03 апреля 2012

У меня есть следующий код, развернутый на сайте https Asp, сборка с MVC 4.0:

public FileResult ANotSoWorkingFunction(string filePath, string fileName)
{
 pathToFile = string.Format("~/{0}/{1}", pathToFile, fileName);
 return File(new FileStream(pathToFile, FileMode.Open), "application/pdf", fileName);
}

Это будет работать (как вы, наверное, многие из вас уже догадались) с Chrome, Firefox и IE9. Но это бросит:

---------------------------
Windows Internet Explorer
---------------------------
Internet Explorer cannot download someFileName from a_site.com.


Internet Explorer was not able to open this Internet site.  The requested site is either unavailable or cannot be found.  Please try again later.
---------------------------
OK   
---------------------------

на IE6,7,8

Буду очень признателен за любые идеи или подсказки, так как я уже провожу весь день, играя с заголовком html.

EDIT:

Вот заголовок из IE7:

HTTP/1.1 200 OK
Cache-Control: private, no-cache="Set-Cookie"
Content-Type: application/pdf
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXAUTH=; expires=Mon, 11-Oct-1999 21:00:00 GMT; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Wed, 04 Apr 2012 08:43:50 GMT
Content-Length: 233324

А вот из IE9:

HTTP/1.1 200 OK
Cache-Control: private, no-cache="Set-Cookie"
Content-Type: application/pdf
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXAUTH=; expires=Mon, 11-Oct-1999 21:00:00 GMT; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Wed, 04 Apr 2012 08:42:14 GMT
Content-Length: 233324

Спасибо,

Ответы [ 3 ]

8 голосов
/ 29 июня 2012

Мне кажется, я тоже столкнулся с вашей проблемой.

Я также использую IIS 7.5 и загружаю PDF с помощью действия по запросу HTTPS. По причинам, которые мне еще предстоит выделить, IIS 7.5, кажется, добавляет no-cache="Set-Cookie" к моему Cache-Control заголовку ответа независимо от того, какие настройки кэша я установил в ответе. Это вызывало довольно хорошо задокументированную проблему no-cache в IE6, IE7 и IE8 .

Чтобы решить эту проблему, я создал небольшую оболочку для FileContentResult, которая очистила заголовки, называлась родительской, а затем установила для Cacheability значение «Private». Это необязательное требование IIS 7.5 добавить no-cache="Set-Cookie" к заголовку, и файл загружен правильно во всех протестированных мной браузерах. Если вы хотите подражать тому, что я сделал, во-первых, вот моя оболочка FileContentResult.

public class PdfContentResult : FileContentResult {

    public PdfContentResult(byte[] data) : base(data, "application/pdf") { }

    public PdfContentResult(byte[] data, string fileName) : this(data) {
        if (fileName == null) {
            throw new ArgumentNullException("fileName");
        }

        this.FileDownloadName = fileName;
    }

    public override void ExecuteResult(ControllerContext context) {
        context.HttpContext.Response.ClearHeaders();

        base.ExecuteResult(context);

        context.HttpContext.Response.Cache.SetCacheability(HttpCacheability.Private);
    }
}

Затем я добавил метод расширения к своему ControllerExtensions, чтобы было легко найти:

public static class ControllerExtensions {

    public static PdfContentResult Pdf(this Controller controller, byte[] fileContents, string fileName) {
        return new PdfContentResult(fileContents, fileName);
    }

}

Наконец, в рамках действия я сделал эквивалент этого:

public ActionResult MyGeneratedPdf() {
    byte[] myPdfContentInByteStream = GetPdfFromModel();
    return this.Pdf(myPdfContentInByteStream, "MyFile.pdf");
}

Очевидно, что если вы загружаете все типы данных, возможно, вы не захотите так тесно связывать обходной путь с PDF.

1 голос
/ 31 мая 2012

Мы решили эту проблему, изменив заголовок элемента управления кэшем перед потоковой передачей файла.

Упрощенный пример кода:

var browserInformation = Request.Browser;

//Set as private if current browser type is IE
Response.AppendHeader("cache-control", 
                    browserInformation.Browser == "IE" ? "private" : "no-cache");

return File(fileName, contentType, downloadFileName);

Это сработало (ууу) .. НО у меня осталась неясность, почему мы должны были сделать это таким образом для этого конкретного сайта. У нас на одном компьютере работает четыре веб-сайта, все по SSL, и только у одного была проблема с заголовком. Я сравнил файлы web.config и посмотрел на настройку в IIS, но не смог пролить дополнительный свет на то, почему на этом сайте явно нужны заголовки.

Если у кого-то есть еще что-то, что можно добавить к вышеперечисленному (для того, чтобы добавить пыль), это было бы здорово.

0 голосов
/ 04 апреля 2012

В более старых версиях IE, если пользователь пытается загрузить файл через соединение HTTPS, любые заголовки ответа, которые препятствуют кэшированию, могут вызвать сбой процесса загрузки файла.Ниже приведены наиболее распространенные заголовки, которые вызывают проблему:

  • Cache-Control со значениями no-cache или no-store
  • Зависит от любого значения
  • Pragmaсо значением no-cache

Вы можете создать атрибут ActionFilterAttribute, который очистит для вас заголовки кэша следующим образом:

public class ClearCacheHeadersAttribute : FilterAttribute, IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        return;
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpContext.Current.Response.Headers.Remove("Cache-Control");
        HttpContext.Current.Response.Headers.Remove("Vary");
        HttpContext.Current.Response.Headers.Remove("Pragma");

        //Set the cache headers any way you like keeping in mind which values can brake the download
    }
}

И украсит ваши действия этим:

[ClearCacheHeaders]
public FileResult ANotSoWorkingFunction(string filePath, string fileName)
{
    pathToFile = string.Format("~/{0}/{1}", pathToFile, fileName);
    return File(new FileStream(pathToFile, FileMode.Open), "application/pdf", fileName);
}
...