如何以编程方式访问ASP.NET/IIS默认错误描述及查询存储位置
关于IIS上ASP.NET默认HTTP错误描述的存储与编程访问
我来给你详细拆解这个问题,分几个部分说清楚:
一、默认错误描述存在哪儿?
首先得明确:这些ASP.NET专属的HTTP错误描述,不是存在IIS的某个配置文件或磁盘文件夹里,而是嵌入在ASP.NET框架的程序集资源当中,属于框架的一部分。
分两种框架情况:
- 传统ASP.NET(.NET Framework):这些文本都在
System.Web程序集的内部资源类里,具体是System.Web.SR(String Resources)这个内部类,对应的资源是编译进程序集的二进制资源,没有单独的磁盘文件。 - ASP.NET Core:默认错误页的文本则在
Microsoft.AspNetCore.Diagnostics这个NuGet包的程序集资源里,比如和StatusCodePagesMiddleware相关的内部资源类,同样是嵌入在程序集里的。
补充一下:如果是IIS自身处理的静态错误(比如非ASP.NET请求的404),才会存在系统目录C:\Windows\System32\inetsrv\errors下的html文件,但你问的是ASP.NET的HTTP错误,重点还是在框架资源里。
二、能不能通过代码访问?当然可以!
不管是传统ASP.NET还是ASP.NET Core,都能通过反射来获取这些内部资源里的文本,因为对应的资源类是内部的,没法直接引用,所以得用反射。
1. 传统ASP.NET(.NET Framework)的实现
比如你要获取404的默认描述,可以写这样的代码:
using System; using System.Reflection; using System.Web; public static string GetAspNetHttpErrorDescription(int statusCode) { // 拿到System.Web程序集 Assembly systemWebAssembly = typeof(HttpException).Assembly; // 获取内部的SR资源类 Type srType = systemWebAssembly.GetType("System.Web.SR"); if (srType == null) return null; // 映射状态码到对应的资源属性名 string resourceName = statusCode switch { 404 => "HttpNotFoundDescription", 403 => "HttpForbiddenDescription", 500 => "HttpInternalServerErrorDescription", // 其他状态码可以自己补充对应的属性名 _ => null }; if (resourceName == null) return null; // 获取静态属性的值 PropertyInfo prop = srType.GetProperty(resourceName, BindingFlags.Static | BindingFlags.NonPublic); return prop?.GetValue(null) as string; }
这里的HttpNotFoundDescription就是对应你提到的那段404描述文本,其他状态码对应的属性名也都是类似的命名规则,比如403是HttpForbiddenDescription。
另外,如果你已经捕获了HttpException,其实它的Message属性里也包含了这个描述(可能会附加URL等信息),但如果要纯描述的话,上面的反射方法更精准。
2. ASP.NET Core的实现
ASP.NET Core的资源类也是内部的,同样用反射来获取,示例代码如下:
using System; using System.Reflection; using Microsoft.AspNetCore.Diagnostics; public static string GetAspNetCoreHttpErrorDescription(int statusCode) { Assembly diagnosticsAssembly = typeof(StatusCodePagesMiddleware).Assembly; // 获取内部的资源类,不同版本可能命名略有差异 Type resourcesType = diagnosticsAssembly.GetType("Microsoft.AspNetCore.Diagnostics.Resources.StatusCodePagesResources"); if (resourcesType == null) return null; // 映射状态码到资源键名 string resourceName = statusCode switch { 404 => "NotFound_Description", 403 => "Forbidden_Description", 500 => "ServerError_Description", // 按需添加其他状态码 _ => null }; if (resourceName == null) return null; // 调用资源类的GetString方法获取文本 MethodInfo getStringMethod = resourcesType.GetMethod("GetString", BindingFlags.Static | BindingFlags.NonPublic, new[] { typeof(string) }); return getStringMethod?.Invoke(null, new object[] { resourceName }) as string; }
注意:不同版本的ASP.NET Core,资源类的命名或者方法可能有小变动,需要根据你使用的框架版本调整。
三、额外小提示
- 如果只是想在自定义错误页里用这些描述,传统ASP.NET里直接用
HttpException.Message也能拿到带描述的信息;ASP.NET Core里可以直接用StatusCodePages中间件的默认文本,但如果需要纯描述内容,反射的方式更靠谱。 - 这些资源文本是和框架版本绑定的,不同.NET Framework或.NET Core版本的文本可能有细微差别,代码要适配对应的版本哦。
内容的提问来源于stack exchange,提问作者Arkiliknam




