简体   繁体   English

在asp.net/mvc中的控制器内部的动作中将标头添加到http响应

[英]adding header to http response in an action inside a controller in asp.net/mvc

I am streaming data from server to client for download using filestream.write . 我正在将数据从服务器流传输到客户端,以使用filestream.write下载。 In that case what is happening is that I am able to download the file but it does not appear as download in my browser. 在这种情况下,发生的事情是我能够下载文件,但在浏览器中却没有下载。 Neither the pop-up for "Save As" appears not "Download Bar" appears in Downloads section. 在“下载”部分中不会出现“另存为”的弹出窗口,而不会出现“下载栏”。 From looking around, I guess I need to include "something" in the response header to tell the browser that there is an attachment with this response. 从四周看,我想我需要在响应标头中包含“某些内容”,以告知浏览器此响应包含附件。 Also I want to set the cookie. 我也想设置cookie。 To accomplish this, this is what I am doing: 为此,我正在做的是:

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

I am getting error that: "System.web.httpcontext.current is a property and is used as a type." 我收到以下错误消息:“ System.web.httpcontext.current是属性,并且用作类型。”

Am I doing the header updating at the right place? 我在正确的位置进行标题更新吗? Is there any other way to do this? 还有其他方法吗?

Yes, You are doing it the wrong way try this, you should add the header inside your action not as an attribute header to your method. 是的,您尝试这样做的方式有误,您应该在操作内添加标头,而不应将其添加为方法的属性标头。

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

or 要么

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

Update As i understand you are making an ajax call to your controller/action which wont work for file download by directly calling an action. 更新据我了解,您正在对控制器/动作进行ajax调用,而无法通过直接调用动作来进行文件下载。 You can achieve it this way. 您可以通过这种方式实现。

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

or 要么

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

In your JS button click you can just do something similar to this. 在您的JS按钮中,您可以执行类似的操作。

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

Please take a look here . 在这里看看。

Following is taken from referenced website. 以下是从引用的网站上获取的。

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: 编辑1:

Adding something that might be more of your interest from our good ol' SO. 通过我们的优质服务添加您可能更感兴趣的产品。 You can check for complete detail 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);
}

Change: 更改:

return RedirectToAction("Index");

to: 至:

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

And move the return statement to inside your using statement. 并将return语句移到using语句内部。

In the past I built a whitelist to allow some domains to iframe my site. 过去,我建立了一个白名单,以允许某些域对我的网站进行内嵌。 Remember Google's image cache used to iframe sites as well. 请记住,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);
        }
    }
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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ASP.NET MVC控制器中的异步操作 - Async action in asp.net mvc controller 在ASP.NET MVC中保护控制器动作 - Securing controller action in ASP.NET MVC ASP.NET 5 MVC 6 XML响应标头 - ASP.NET 5 MVC 6 XML response header 在asp.net mvc 4中,有没有一种方法可以在基本控制器中创建索引操作,并将该操作的视图共享给多个控制器? - is there a way in asp.net mvc 4 to create an Index Action inside Base Controller and Share the view of this Action to multiple Controllers? 给定一个URL和HTTP动词,如何在ASP.NET MVC / Web API中解析控制器/动作? - Given a URL and HTTP verb, how can I resolve the controller/action in ASP.NET MVC/Web API? 在asp.net mvc中设置索引操作默认操作控制器 - set index action default action controller in asp.net mvc ASP.NET MVC从同一控制器发布到控制器操作 - ASP.NET MVC post to controller action from same controller ASP.NET MVC Razor:如何在控制器动作中呈现Razor Partial View的HTML - ASP.NET MVC Razor: How to render a Razor Partial View's HTML inside the controller action 动作中的响应标头在视图中消失 - asp net mvc - response header set in action disappears in view - asp net mvc ASP.NET.MVC 5将权限添加到控制器的操作 - ASP.NET.MVC 5 Adding permissions to action of a controller
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM