2013-04-18 9 views
8

Я передаю данные с сервера на клиент для загрузки с использованием filestream.write. В этом случае происходит то, что я могу загрузить файл, но он не отображается как загрузка в моем браузере. Ни всплывающее окно для «Сохранить как» не появляется, а «Панель загрузки» появляется в разделе «Загрузки». От взгляда вокруг, я думаю, мне нужно включить «что-то» в заголовок ответа, чтобы сообщить браузеру, что есть вложение с этим ответом. Также я хочу установить cookie. Для достижения этой цели, это то, что я делаю:Добавление заголовка в ответ HTTP в действии внутри контроллера в asp.net/mvc

 [HttpContext.Current.Response.AppendHeader("Content-Disposition","attachment;filename=" & name)] 
    public ActionResult Download(string name) 
    { 
      // some more code to get data in inputstream. 

      using (FileStream fs = System.IO.File.OpenWrite(TargetFile)) 
      { 
       byte[] buffer = new byte[SegmentSize]; 
       int bytesRead; 
       while ((bytesRead = inputStream.Read(buffer, 0, SegmentSize)) > 0) 
       { 
        fs.WriteAsync(buffer, 0, bytesRead); 
       } 
      } 
     } 
     return RedirectToAction("Index"); 
    } 

Я получаю сообщение об ошибке, что: «System.web.httpcontext.current это свойство и используется в качестве типа.»

Я делаю обновление заголовка в нужном месте? Есть ли другой способ сделать это?

ответ

11

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

HttpContext.Current.Response.AppendHeader("Content-Disposition","attachment;filename=" & name) 

или

Request.RequestContext.HttpContext.Response.AddHeader("Content-Disposition", "Attachment;filename=" & name) 

Update Как я понимаю, вы делаете вызов Ajax для вашего контроллера/действия, которые не будут работать для загрузки файлов с помощью прямого вызова действия. Вы можете добиться этого таким образом.

public void Download(string name) 
     { 
//your logic. Sample code follows. You need to write your stream to the response. 

      var filestream = System.IO.File.ReadAllBytes(@"path/sourcefilename.pdf"); 
      var stream = new MemoryStream(filestream); 
      stream.WriteTo(Response.OutputStream); 
      Response.AddHeader("Content-Disposition", "Attachment;filename=targetFileName.pdf"); 
      Response.ContentType = "application/pdf"; 
     } 

или

public FileStreamResult Download(string name) 
    { 
     var filestream = System.IO.File.ReadAllBytes(@"path/sourcefilename.pdf"); 
     var stream = new MemoryStream(filestream); 


     return new FileStreamResult(stream, "application/pdf") 
     { 
      FileDownloadName = "targetfilename.pdf" 
     }; 
    } 

В кнопке JS щелчок мыши вы можете просто сделать что-то похожее на это.

$('#btnDownload').click(function() { 
      window.location.href = "controller/download?name=yourargument"; 
    }); 
+0

Я пытался сделать это.Но он пока не показывает диалоговое окно «Сохранить как», а также индикатор выполнения загрузки в разделе загрузки браузера. – ezile

+0

Это работает для меня, и я вижу, как html-образ просматривается в моем тестовом примере. Для вас это может быть потому, что вы перенаправляетесь к действию. Однако я не пробовал этот сценарий. Просто попробуйте разместить этот заголовок под индексом только для попытки. – PSL

+0

Я расскажу немного больше. Я на странице «Индекс», а затем нажимает «Загрузить», а затем вызывает действие «Загрузить» через JavaScript. Вышеприведенный код написан в действии Download. И после потоковой передачи файла пользователю, я перенаправляю на страницу индекса. Я смущен, когда я должен сказать браузеру, что есть загрузка. Я имею в виду, что я отправляю материал с помощью FileStream.WriteSync, поэтому, я думаю, мне нужно сообщить браузеру перед отправкой файла, что есть вложение, и, таким образом, появится всплывающее диалоговое окно «Сохранить как». Я думаю, что я запутался в рабочем процессе здесь и, следовательно, не делаю, когда и где я должен делать изменения. – ezile

3

Просьба посмотреть here.

Ниже приведена ссылка на веб-сайт, на который делается ссылка.

public FileStreamResult StreamFileFromDisk() 
{ 
    string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/"; 
    string fileName = "test.txt"; 
    return File(new FileStream(path + fileName, FileMode.Open), "text/plain", fileName); 
} 

Edit 1:

Добавление что-то, что могло бы быть больше интерес от нашего старого доброго»SO. Вы можете проверить полную информацию here.

public ActionResult Download() 
{ 
    var document = ... 
    var cd = new System.Net.Mime.ContentDisposition 
    { 
     // for example foo.bak 
     FileName = document.FileName, 

     // always prompt the user for downloading, set to true if you want 
     // the browser to try to show the file inline 
     Inline = false, 
    }; 
    Response.AppendHeader("Content-Disposition", cd.ToString()); 
    return File(document.Data, document.ContentType); 
} 
0

Изменение:

return RedirectToAction("Index"); 

к:

return File(fs, "your/content-type", "filename"); 

И подвигать возвратную заявление внутри с помощью заявления.

0

В прошлом я построил белый список, чтобы разрешить некоторым доменам iframe мой сайт. Помните кеш-образ Google, используемый также для сайтов iframe.

static HashSet<string> frameWhiteList = new HashSet<string> { "www.domain.com", 
                "mysub.domain.tld", 
                "partner.domain.tld" }; 

    protected void EnforceFrameSecurity() 
    { 
     var framer = Request.UrlReferrer; 
     string frameOptionsValue = "SAMEORIGIN"; 

     if (framer != null) 
     { 
      if (frameWhiteList.Contains(framer.Host)) 
      { 
       frameOptionsValue = string.Format("ALLOW-FROM {0}", framer.Host); 
      } 

     } 

     if (string.IsNullOrEmpty(HttpContext.Current.Response.Headers["X-FRAME-OPTIONS"])) 
     { 
      HttpContext.Current.Response.AppendHeader("X-FRAME-OPTIONS", frameOptionsValue); 
     } 
    } 
0
public FileResult DownloadDocument(string id) 
     { 
      if (!string.IsNullOrEmpty(id)) 
      { 
       try 
       { 
        var fileId = Guid.Parse(id); 

       var myFile = AppModel.MyFiles.SingleOrDefault(x => x.Id == fileId); 

       if (myFile != null) 
       { 
        byte[] fileBytes = myFile.FileData; 
        return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, myFile.FileName); 
       } 
      } 
      catch 
      { 
      } 
     } 

     return null; 
    }