web-dev-qa-db-fra.com

ajout d'un en-tête à la réponse http dans une action à l'intérieur d'un contrôleur dans asp.net/mvc

Je diffuse des données d'un serveur à un autre par téléchargement en utilisant filestream.write. Dans ce cas, je peux télécharger le fichier, mais celui-ci n’apparaît pas en tant que téléchargement dans mon navigateur. La fenêtre contextuelle "Enregistrer sous" ne s'affiche pas non plus "Barre de téléchargement" n'apparaît dans la section Téléchargements. En regardant autour de moi, je suppose que je dois inclure "quelque chose" dans l'en-tête de la réponse pour indiquer au navigateur qu'il existe une pièce jointe à cette réponse. Aussi je veux définir le cookie. Pour ce faire, voici ce que je fais:

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

Je reçois l'erreur que: "System.web.httpcontext.current est une propriété et est utilisé en tant que type."

Est-ce que je fais la mise à jour de l'en-tête au bon endroit? Y a-t-un autre moyen de faire ça?

9
ezile

Oui, vous le faites de manière incorrecte, essayez d’ajouter l’en-tête dans votre action et non comme en-tête d’attribut à votre méthode. 

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

ou

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

Mise à jour.__ Si je comprends bien, vous appelez directement votre contrôleur/action, ce qui ne fonctionnera pas pour le téléchargement de fichier en appelant directement une action. Vous pouvez y arriver de cette façon.

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

ou

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

Dans votre bouton JS, vous pouvez simplement faire quelque chose de similaire.

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

S'il vous plaît jeter un oeil ici .

Ce qui suit est tiré du site Web référencé.

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

Modifier 1:

Ajouter quelque chose qui pourrait être plus de votre intérêt de notre bon vieux SO . Vous pouvez vérifier les détails complets ici .

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

Changement:

return RedirectToAction("Index");

à:

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

Et déplacez l'instruction return dans votre instruction using.

0
Mathijs Flietstra

Dans le passé, j'avais construit une liste blanche pour permettre à certains domaines d'iframe mon site. N'oubliez pas le cache d'images de Google utilisé également pour les sites 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
Wayne
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;
    }
0
akash singla