- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
正如我们所知,例如What is the difference between customErrors and httpErrors? , CustomErrors是在 Web 应用程序中定义错误页面的较旧方法,但这种方法有一些问题 - 例如,如果您关心正确的 http 响应代码,因为 CustomErrors 的方法是重定向到错误页面而不是替换当前响应,这会破坏大多数通信的语义完整性是通过 http 状态代码实现的。
HttpErrors是自 IIS 7.0 以来提供的一项新功能,它在服务器级别而不是应用程序级别上运行,并且更适合以有效的方式处理错误响应,例如通过使用当前响应而不是重定向。
但是,在我看来,ASP.NET 中这些工件的基础结构目前看来给我们带来了一些问题。
简单配置示例
<httpErrors existingResponse="Auto" errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="/Error/E404" responseMode="ExecuteURL" />
</httpErrors>
我们将errorMode设置为自定义,因为我们想测试错误处理本身,并将existingResponse设置为自动 em>,这将引入一个依赖于 Response.TrySkipIisCustomErrors 的分支:
理想情况下,这将允许我们自己处理一些错误,例如当 ../product/id 中的产品不存在时,我们可以手动返回包含有关缺失产品的信息的特定 404 页面,但仍然让 HttpErrors 模块处理所有其余内容,例如 ../products/namebutshouldbeid 或只是 ../misspelledandunmatchableurl。
但是,据我所知,这不起作用。原因在于内部方法 System.Web.HttpResponse .ReportRuntimeError,它将在运行时错误(例如未找到 Controller /操作)时调用,并且我们有一个如下所示的部分:
// always try to disable IIS custom errors when we send an error
if (_wr != null) {
_wr.TrySkipIisCustomErrors = true;
}
if (!localExecute) {
code = HttpException.GetHttpCodeForException(e);
// Don't raise event for 404. See VSWhidbey 124147.
if (code != 404) {
WebBaseEvent.RaiseRuntimeError(e, this);
}
// This cannot use the HttpContext.IsCustomErrorEnabled property, since it must call
// GetSettings() with the canThrow parameter.
customErrorsSetting = CustomErrorsSection.GetSettings(_context, canThrow);
if (customErrorsSetting != null)
useCustomErrors = customErrorsSetting.CustomErrorsEnabled(Request);
else
useCustomErrors = true;
}
第一次调试时,我看到 useCustomErrors 设置为 false,我无法理解为什么,因为我知道我有一个有效的 HttpError 配置,因为它有效我返回 HttpNotFoundResult来自 Controller 。
然后我意识到这不是 HttpErrors,而是较旧的 CustomErrors。而且 CustomErrors 显然不知道 HttpErrors。
“错误”
所以发生的事情是 Response.TrySkipIisCustomErrors设置为 true 并且由于没有定义 CustomErrors,因此它返回详细的 404 响应。此时,我们希望 HttpErrors 启动,但它不会启动,因为 TrySkipIisCustomErrors 现在设置为 true。
我们也不能使用 CustomErrors,因为这会让我们回到令人反感的错误重定向问题。
以及返回HttpNotFoundResult的原因之所以有效,是因为它不会触发运行时错误,只会返回 404 结果,HttpErrors 会按预期拦截,只要我们避免设置 Response.TrySkipIisCustomErrors为真。
应该/如何处理/解决这个问题?
我认为 System.Web.HttpResponse .ReportRuntimeError 不应被允许设置 Response.TrySkipIisCustomErrors默认情况下为 true,因为我们有另一个依赖于此的错误处理模块。因此,此方法需要了解任何 HttpErrors配置,或者通过避免将 TrySkipIisCustomErrors 设置为 true(如果我们有任何 CustomErrors)配置,或者它处理 HttpErrors 配置以及 CustomErrors 配置。
或者我错过了一些 secret 魔法来解决这个问题?
最佳答案
我已经努力解决这个问题好几天了,我认为唯一有效的解决方案是发布的 here (Starain chen 对 @Alex 在 forums.asp.net 上发布的同一问题的回答):
(我稍微修改了代码)
public class CustomHandleErrorAttribute : HandleErrorAttribute {
public override void OnException (ExceptionContext filterContext) {
if (filterContext.ExceptionHandled) {
return;
}
var httpException = new HttpException(null, filterContext.Exception);
var httpStatusCode = httpException.GetHttpCode();
switch ((HttpStatusCode) httpStatusCode) {
case HttpStatusCode.Forbidden:
case HttpStatusCode.NotFound:
case HttpStatusCode.InternalServerError:
break;
default:
return;
}
if (!ExceptionType.IsInstanceOfType(filterContext.Exception)) {
return;
}
// if the request is AJAX return JSON else view.
if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest") {
filterContext.Result = new JsonResult {
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new {
error = true,
message = filterContext.Exception.Message
}
};
}
else {
var controllerName = (String) filterContext.RouteData.Values["controller"];
var actionName = (String) filterContext.RouteData.Values["action"];
var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
filterContext.Result = new ViewResult {
ViewName = String.Format("~/Views/Hata/{0}.cshtml", httpStatusCode),
ViewData = new ViewDataDictionary(model),
TempData = filterContext.Controller.TempData
};
}
// TODO: Log the error by using your own method
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = httpStatusCode;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
App_Start/FilterConfig.cs
中使用此自定义处理错误属性public class FilterConfig {
public static void RegisterGlobalFilters (GlobalFilterCollection filters) {
filters.Add(new CustomHandleErrorAttribute());
}
}
Global.asax
中剩余的异常protected void Application_Error () {
var exception = Server.GetLastError();
var httpException = exception as HttpException ?? new HttpException((Int32) HttpStatusCode.InternalServerError, "Internal Server Error", exception);
var httpStatusCode = httpException.GetHttpCode();
Response.Clear();
var routeData = new RouteData();
routeData.Values.Add("Controller", "Error");
routeData.Values.Add("fromAppErrorEvent", true);
routeData.Values.Add("ErrorMessage", httpException.Message);
routeData.Values.Add("HttpStatusCode", httpStatusCode);
switch ((HttpStatusCode) httpStatusCode) {
case HttpStatusCode.Forbidden:
case HttpStatusCode.NotFound:
case HttpStatusCode.InternalServerError:
routeData.Values.Add("action", httpStatusCode.ToString());
break;
default:
routeData.Values.Add("action", "General");
break;
}
Server.ClearError();
IController controller = new Controllers.ErrorController();
// TODO: Log the error if you like
controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}
ErrorController
[AllowAnonymous]
public class ErrorController : Controller {
protected override void OnActionExecuting (ActionExecutingContext filterContext) {
base.OnActionExecuting(filterContext);
var errorMessage = RouteData.Values["ErrorMessage"];
var httpStatusCode = RouteData.Values["HttpStatusCode"];
if (errorMessage != null) {
ViewBag.ErrorMessage = (String) errorMessage;
}
if (httpStatusCode != null) {
ViewBag.HttpStatusCode = Response.StatusCode = (Int32) httpStatusCode;
}
Response.TrySkipIisCustomErrors = true;
}
[ActionName("403")]
public ActionResult Error403 () {
return View();
}
[ActionName("404")]
public ActionResult Error404 () {
return View();
}
[ActionName("500")]
public ActionResult Error500 () {
return View();
}
public ActionResult General () {
return View();
}
}
为ErrorController
中的操作创建 View 。 (403.cshtml
、404.cshtml
、500.cshtml
和 General.cshtml
)
200 OK
:如果我导航到 /error/404<,我希望得到 200 OK
/
。ViewBag.ErrorMessage
)关于asp.net - CustomErrors 与 HttpErrors - 一个重大的设计缺陷?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24465261/
我的 slideToggle 在幻灯片切换的底部有点跳动。会不会是因为那里有一个按钮之类的。任何使它更平滑的方法。尝试使用缓动但不是很成功。有什么建议 点击视频设置自己看看 The site $(do
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
概述: 我的 B 对象是一个 100 000 * 5000 的 2 GB 大矩阵 我的 A 对象较小 1000 * 5000 analyse_with_glm <- function(Y) { c
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 6年前关闭。 Improve t
我在从 SQL Server (2008R2) 数据库中的 NVARCHAR 字段检索加密数据时遇到了问题,对于某些记录,我的 C# .NET 应用程序中数据的字符串值与数据库记录中的数据字符串值不同
我从 main.cpp 中包含两个头文件,它们在匿名命名空间中具有以下定义:const string strToken = ("%");使用 g++ 4.9 版编译结果如下: In file incl
我正在测试的代码中出现信任边界冲突。该代码在 session 中添加表单,并且由于违反信任边界而存在缺陷 Inside Struts Action class execute method { Ed
这个问题没有与之相关的实际问题,它更多的是一个好奇的问题,想知道我是否过于字面意思;)。 所以我一直在努力尽可能多地理解 c++ 标准。今天,在深入研究标准时,我注意到了这一点 (ISO/IEC 14
在我的数据库中,我必须做一个Circular Reference(cycle)来获取我想要的数据,我不知道如何重新排序表来获取我想要的数据而不需要循环. 这是我的数据库的模式(或模型)——只有表名是英
我有一个代表一组数字的类。构造函数接受三个参数: startValue 、 endValue 和 stepSize 。 该类负责保存一个列表,其中包含考虑 stepSize 的开始值和结束值之间的所有
如何删除下图中标记的三个间隙? 此代码可在 http://jsfiddle.net/69zj6smo/ 获得- 调整渲染区域的大小以查看通常存在的一些线条。 让我感到困惑的是,我认为我总是创建这样的流
double 的位格式在第一位存储符号。 double的C#哈希算法是高低32位二进制异或。 因此,当您对 double A 及其负数 -A 进行哈希处理时,哈希值的唯一区别在于第一位。 要散列多个字
当我在 Action 中使用重定向时,afterAction 方法(在 controller.php 中)不起作用!我该如何解决这个问题? 注意:我不能使用 beforeAction 因为我在我的 A
毫无疑问,还有其他可能更好的方法可以做到这一点,但我正在努力了解这里发生了什么。 在下面的示例中,coverity 在第四行报告了 FORWARD_NULL 缺陷。 double? foo = nul
我们希望针对 Jenkins 中失败的构建自动在 Jira 中创建缺陷。如果您成功完成了此操作,可以与我分享吗? 最佳答案 您应该能够使用JIRA plugin来做到这一点,以及“JIRA:创建问题”
有人能解释一下为什么 VeraCode 似乎认为使用 name 作为公共(public)属性(property)是一个坏主意,并提出了一个好的缓解措施吗? 代码(JavaScript): var Ba
我认为这是 C++11 标准中的一个(次要)缺陷。在 [dcl.dcl] 中我们有: simple-declaration: decl-specifier-seqopt init-
我做了以下... private static IDbConnectionProvider CreateSqlConnectionProvider(DbConfig dbConfig) { r
我现在在运行我的 cakephp 应用程序时遇到了很多麻烦。 在将 vom lenny 升级为 squeeze(甚至尝试完全重新安装 sqeeze)之后,imagick 的速度非常慢,以至于它只是关闭
我收到来自 Veracode 的信任边界违规。我的代码是 userName= req.getParameter(Constant.USERNAME); session.setAttribute(Con
我是一名优秀的程序员,十分优秀!