当我的应用程序在AJAX请求期间遇到类型UnauthorizedAccessException
的异常时,我想自己处理该行为并返回自定义JSON响应。
因此,我在基本控制器中重写了OnException
方法,我的所有控制器都继承了该方法,如下所示:
protected override void OnException(ExceptionContext filterContext)
{
var exception = filterContext.Exception;
if (exception is UnauthorizedAccessException)
{
filterContext.ExceptionHandled = true;
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
filterContext.HttpContext.Response.ContentType = "application/json";
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize(new { IsUnauthenticated = true });
filterContext.HttpContext.Response.Write(json);
filterContext.HttpContext.Response.End();
}
else
{
filterContext.Result = RedirectToAction("LogOut", "Account");
}
}
else
{
// Allow the exception to be processed as normal.
base.OnException(filterContext);
}
}
现在,这几乎可以完全满足我的要求。如果在AJAX请求期间发生异常,我的JavaScript将根据需要获取正确的JSON对象。
但是,问题是应用程序随后在内部遭受HttpException
的影响,并显示以下消息:
发送HTTP标头后无法重定向。
以及来自异常的堆栈跟踪:
在System.Web.HttpResponse.Redirect(字符串url,布尔值endResponse,布尔值永久性) 在System.Web.Security.FormsAuthenticationModule.OnLeave(Object source,EventArgs eventArgs) 在System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 在System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep步骤) 在System.Web.HttpApplication.ExecuteStep(IExecutionStep步骤,布尔值并已完成)
将断点添加到Application_Error
的{{1}}方法中时,会得到以下异常信息:
MvcApplication
因此,尽管我的应用程序产生的结果完全符合我的用户体验。我有一个“幕后”异常,我真的不想发生。
这是怎么回事?我该怎么做才能防止异常发生?
答案 0 :(得分:1)
从评论继续,我认为由于字符限制,最好将其发布为答案。这部分是答案,因为我前面没有合适的项目要测试。
当我在评论中说我无法复制时,那是因为我在我正在处理的项目中运行了那些测试,这些项目是WebApi2,并且我不会有相同的行为。
如果我的想法正确,那么您的问题就在于您正在将类似API的功能实现到MVC项目中,当然,您所看到的只是预期的行为。
当您收到UnauthorizedException时,框架将尝试自动将您重定向到登录屏幕(或错误页面)。您需要(显然)禁用该行为。
您可以尝试使用以下方法在处理程序中将其抑制:
con = sqlite3.connect('databaseTest.db')
cur = con.cursor()
cur.execute("SELECT LOAN_AMOUNT FROM funded")
loan_amount = cur.fetchall()
loan_amount_list = [i[0] for i in loan_amount]
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
x = loan_amount_list
最终结果应该类似于:
filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
filterContext.HttpContext.Response.Redirect(null);
如果这不起作用;您的身份验证中间件也可能负责设置此重定向,但很遗憾,该重定向将在其他地方设置。
答案 1 :(得分:0)
我的其他答案是错误的,我刚刚对其进行了测试。
该问题的解决方案与我之前给您的解决方案略有不同。您的中间件就是导致问题的原因。
我怀疑您正在使用我正在使用的东西; Microsoft.ASPNET.Identity。
在Startup.cs内部,您需要添加OnApplyRedirect委托。
您的代码应类似于我的代码:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)),
OnApplyRedirect = ctx =>
{
// add json response here...
ctx.RedirectUri = null;
}
}
});
从原始处理程序中移出响应,并将其添加到ctx.Response ...
希望这将使其重回正轨。在OnApplyRedirect内部,您可能需要检查它是否是ajax请求,然后禁用重定向,否则您将获得难看的asp默认错误页面。.:-)