当请求离开asp:multiview或ajax时,Response.End()之后没有写入响应

时间:2017-03-31 22:53:31

标签: c# asp.net ajax webforms

我编写了一个HttpModule来拦截,评估和授权请求,检查记录的用户是否具有对所请求的url的适当访问权限,这是用ASP.NET 2.0编写的一个非常古老的遗留系统(网页,而不是Web应用程序),客户不希望移植到更新的框架。已在登录时加载和缓存限制。

一切正常,除非某个页面包含<asp:MultiView>组件或者有一个启动ajax方法的按钮。当其中一种情况发生,并且用户无权访问该网址时,会弹出一个警告框,其中显示“未知错误”消息,该消息来自ThreadAbortException方法引发的Response.End()

问题是:为什么我的“未授权”消息被异常中的“未知错误”覆盖,仅在这两种情况下?

是否有办法使用数据库和缓存执行Url授权系统,而不会使Web.config与旧的ASP.NET样本等角色混杂在一起?

// My module init method.
public void Init(HttpApplication context)
{
    context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);

    // PreRequestHandlerExecute is the first stage at ASP.NET Pipeline
    // where we could get a fulfilled Session variable
}

private void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
    HttpApplication application = (HttpApplication)sender;
    HttpContext context = application.Context;

    // additional request filtering/validation/etc.

    LoggedUser user = (LoggedUser)application.Session["user"];

    string path = context.Request.Path;

    // more checks and rules...

    if (!checkUserAuthorization(path, user))
    {
        context.Response.Write("<script>alert('Unauthorized. Contact your manager.');</script>");
        context.Response.Write("<script>window.history.back();</script>");
        context.Response.StatusCode = 403;
        context.Response.End();
    }
}

编辑:我已经尝试过的(没有目标):

  • Response.OutputStream.Close();
  • Response.Flush();
  • HttpApplication.CompleteRequest();

2 个答案:

答案 0 :(得分:0)

它是设计的。你必须忽略它并为该异常添加一个catch。

try {
   context.Response.End();
}
catch{}

答案 1 :(得分:0)

<强>前言

经过大量研究,终于得到了它。考虑到ASP.NET 2.0,关于AJAX操作,我工作的项目使用名为&#34; Atlas&#34;,which in turn got renamed to ASP.NET AJAX的Microsoft组件。在编写此系统时,开发人员使用beta ASP.NET AJAX(代号&#34; Atlas&#34;)来解决所有ajax和部分渲染需求。

我需要深入挖掘源代码(感谢Reflector),以便了解并检查从哪里开始#34;未知错误&#34;来了。

在Microsoft.Web.Atlas中,有一个名为Microsoft.Web.Resources.ScriptLibrary.*.Atlas.js的文件(其中*可以是DebugRelease),它在运行时通过{ {1}}&#34;代理&#34;。

这个javascript文件有一个错误,因为它希望ASP.NET请求总是返回一个WebResource.axd响应代码,在我的代码中它没有发生(我回复了{{ 1}}我模块的代码。)

<强>代码

来自HTTP 200 (OK)的{​​{1}}:

403 Forbidden

从此代码中,我们可以看到,由于响应代码不是Microsoft.Web.Resources.ScriptLibrary.*.Atlas.js,因此WebResource.axd变量不会被设置,而此this._onFormSubmitCompleted = function(sender, eventArgs) { var isErrorMode = true; var errorNode; var delta; if (sender.get_statusCode() == 200) { delta = sender.get_xml(); if (delta) { errorNode = delta.selectSingleNode("/delta/pageError"); if (!errorNode) { isErrorMode = false; } } } if (isErrorMode) { if (errorNode) { pageErrorMessage = errorNode.attributes.getNamedItem('message').nodeValue; } else { pageErrorMessage = 'Unknown error'; } this._enterErrorMode(pageErrorMessage); return; } // Code continues. } 语句将始终为{ {1}}。

在这种情况下,我有两个选项:始终返回200 OK并修改所有包含errorNode的网页,并在每个网页上添加if (errorNode)标记,或取代该脚本如果您考虑false个回复,请将其加载到主页面的HTTP 200标记下方。

当使用ScriptManager和UpdatePanels(官方的here),通过订阅<atlas:ScriptManager>事件)时,有很多关于如何进行正确错误处理的教程,但这个beta版本(阿特拉斯)根本没有这个活动。