测试环境中捕获的Exception无法转为HttpException?求助排查原因
我遇到一个奇怪的问题:在子视图中抛出HttpException后,上层通用Razor视图的try-catch块捕获到的异常无法转换为HttpException——本地运行完全正常,但测试环境里ex.GetType()返回的就是Exception类型,不是预期的HttpException。
补充上下文:我有一个通用Razor视图,里面用try-catch捕获Exception,并调用子视图;子视图在特定逻辑分支会抛出HttpException(400,"Not Found")。但在测试环境中,通用视图里判断ex.GetType() == typeof(HttpException)始终不成立,导致无法处理400错误的逻辑。
子视图代码:
... } else { throw new HttpException(400,"Not Found"); }
通用视图代码:
try { @Html.CachedPartial(moduleItem.DocumentTypeAlias, moduleItem, 60 * 60 * 24 * 365, contextualKeyBuilder: (model, viewData) => { return string.Format("{0}|{1}", moduleItem.Id, Request.QueryString); }, viewData: ViewData) } catch (Exception ex) { // 测试环境中,这里ex.GetType()是Exception,不是HttpException if (ex != null && ex.GetType()== typeof(HttpException)) { var httpExp = ex as HttpException; var code = httpExp.GetHttpCode(); if (code == 400) { HttpContext.Current.Response.StatusCode = (int)HttpStatusCode.NotFound; var xpathQuery = String.Format("//error404"); var umbracoHelper = new UmbracoHelper(UmbracoContext.Current); var contentService = umbracoHelper.TypedContentAtXPath(xpathQuery); var culture = System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName; var moduleItem404 = contentService.FirstOrDefault(x=> x.GetCulture().TwoLetterISOLanguageName== culture); @Html.CachedPartial(moduleItem404.DocumentTypeAlias, moduleItem404, 60 * 60 * 24 * 365, contextualKeyBuilder: (model, viewData) => { return string.Format("{0}|{1}", moduleItem404.Id, Request.QueryString); }, viewData: ViewData) } else { throw ex; } } else { throw ex; } }
结合本地正常、测试环境异常的差异,给你几个排查方向:
先查程序集版本是否一致:
HttpException属于System.Web程序集,测试环境和本地的该程序集版本可能不匹配。你可以对比两边bin目录下的System.Web.dll版本,或者在代码里输出typeof(HttpException).Assembly.FullName和ex.GetType().Assembly.FullName,看看是否一致——如果不一致,说明类型加载出了问题,得统一程序集版本。排查异常是否被包装了:有时候Umbraco的缓存机制或者ASP.NET框架会把原始异常包装成通用
Exception再抛出。你可以在catch块里打印ex.InnerException的信息,看看里面是不是藏着你抛出的HttpException。如果是,修改判断逻辑:var httpExp = ex as HttpException ?? ex.InnerException as HttpException; if (httpExp != null) { // 原来的处理逻辑 }检查测试环境的自定义错误配置:测试环境的
web.config里如果开了<customErrors>,ASP.NET可能会自动转换HttpException。你可以临时把mode设为Off测试:<customErrors mode="Off" />如果问题消失,就需要调整自定义错误的配置,或者在处理异常时兼容这种情况。
暂时禁用缓存试试:你用了
@Html.CachedPartial,测试环境的缓存策略可能和本地不同,导致异常在缓存处理中被转换。先换成普通的@Html.Partial测试,如果问题解决,再去排查Umbraco缓存的配置或逻辑差异。
内容的提问来源于stack exchange,提问作者Rui Estreito

