解决服务器无法在已发送 HTTP 标头之后设置状态导致的一个问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sxf359/article/details/77285294

在错误日志中经常看到服务器无法在已发送 HTTP 标头之后设置状态的提示。英文提示应是:server cannot set status after http headers have been sent

这个问题是asp.net MVC特有的现象,在webform 中从来没出现这类问题。很清楚是服务端跳转的时候出现的问题。但是要解决很难,网上的各种办法都有尝试,但该出现还出现。成了顽疾了。这不,我在stackoverflow 上看到一个帖子写了一个解决办法,如获至宝,然后添加实行。

首先在继承AuthorizeAttribute 的类的protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 方法中增加了几行代码。


 

 protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {

            base.HandleUnauthorizedRequest(filterContext);

            #region solution server cannot set status after http headers have been sent
            var ctx = filterContext.HttpContext;
            //If you are using .NET 4.5 +, add this line before Response.StatusCode
            filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
            ctx.Response.StatusCode = (int)HttpStatusCode.Forbidden;
            ctx.Response.End();
            #endregion

        }

第二个,在global.asax 中的 Application_BeginRequest 增加了两行代码:

 protected void Application_BeginRequest(object sender, EventArgs e)
        {
            Response.Clear();
            // Buffer response so that page is sent
            // after processing is complete.
            Response.BufferOutput = true;
        }

加上后观察了一天,仍然有服务器无法在已发送 HTTP 标头之后设置状态这样的错误提示,看来不起作用啊。由于没有其他影响,这些代码虽然不起作用,但是并没有删除。而过了几天,我在做页面测试的时候,突然发现,当无权限的时候,页面会出现空白,没有任何提示。而原来设置的是当无权限操作该页面的时候,跳转到无权限提示页面。当时觉得可能是浏览器新添加的安全功能。没多久,公司的同事也反应过来了这种问题,感觉这样操作很不方便。我才终于重视其这个问题。由于没权限的时候一片空白。我用fiddler 抓包软件进行测试。发觉访问此页面的时候报的是403 禁止访问。这时我才意识到,这恐怕不是浏览器新增加了安全功能,而有可能是我新添加的代码导致的问题。先禁用了global.asax 中的 Application_BeginRequest 中的两行代码,问题依旧。不是这里的问题。然后禁用继承AuthorizeAttribute 的 HandleUnauthorizedRequest 方法中的几行代码。这时,跳转到无权限页面正常了。这时在分析这几行代码 HttpStatusCode.Forbidden ,这不就是403禁止访问吗。看来这个stackoverflow 的解决方案并不适合我这个问题。
展开阅读全文

服务器无法发送 HTTP 标头之后追加标头。

11-25

/// rn /// 下载文件(查看文件)rn /// rn /// 在客户端显示的文件名(需要后缀)rn /// 打开的路径(相对路径)rn /// 下载的时候是否是分批次下载(适用于比较大的文件)rn public static void DownLoadFile(string clientFileName, string path, bool isSplit = true)rn rn if (isSplit)rn rn System.IO.FileInfo fileinfo = new System.IO.FileInfo(path);rn if (fileinfo.Exists)rn rn const long size = 102400;rn byte[] buffer = new byte[size];rn Response.Clear();rn System.IO.FileStream istream = System.IO.File.OpenRead(path);rn long datalengthToread = istream.Length;rn Response.ContentType = "applocation/octet-stream";rn StringBuilder sb = new StringBuilder("attachment;filename=");rn sb.Append(HttpUtility.UrlEncode(clientFileName));rn Response.AddHeader("Content-Disposition", sb.ToString());rn while (datalengthToread > 0 && Response.IsClientConnected)rn rn int lengthRead = istream.Read(buffer, 0, Convert.ToInt32(size));rn Response.OutputStream.Write(buffer, 0, lengthRead);rn Response.Flush();rn datalengthToread = datalengthToread - lengthRead;rn rn Response.Close();rn rnrn rn elsern rn Response.Clear();rn Response.AddHeader("Content-Disposition", "attachment; filename=" + clientFileName);rn Response.ContentType = "application/octet-stream";rn Response.Filter.Close();rn Response.TransmitFile(Server.MapPath(path));rn Response.End();rn rn rnrnrn[color=#FF0000]我的下载文件的方法是写在类库里面的;我点击第一次的时候很好!第二次就出现了这样的问题!rnserver/responses是我封装的属性[/color]rnrnrn[HttpException (0x80004005): 服务器无法在发送 HTTP 标头之后追加标头。]rn System.Web.HttpResponse.AppendHeader(String name, String value) +9681561rn System.Web.HttpResponse.AddHeader(String name, String value) +8rn Help.DownLoadFile(String clientFileName, String path, Boolean isSplit) in C:\Users\amber\Documents\Visual Studio 2010\Projects\YiLiJian\Common\Help.cs:324rn ViewData_Default.Button1_Click(Object sender, EventArgs e) in c:\Users\amber\Documents\Visual Studio 2010\Projects\YiLiJian\UI\ViewData\Default.aspx.cs:24rn System.Web.UI.WebControls.Button.OnClick(EventArgs e) +9552874rn System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +103rn System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10rn System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13rn System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +35rn System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1724 论坛

没有更多推荐了,返回首页