.net - .NET MVC/WEB API 2 - 调试与发布中的异常处理
问题描述
包含 Web Api 2 控制器的 .NET MVC 应用程序。经过一些谷歌搜索,我知道这是处理 api 控制器中错误的正确方法,方法是抛出带有适当状态代码的 HttpResponseException:
控制器动作方法:
[System.Web.Http.Authorize]
public IHttpActionResult GetEntities() {
var entsDb = db.MyEntities;
/*
//uncomment this block to test exception throw
var response = new HttpResponseMessage(HttpStatusCode.NotFound) {
Content = new StringContent("some error message", System.Text.Encoding.UTF8, "text/plain"),
StatusCode = HttpStatusCode.NotFound
};
throw new HttpResponseException(response);
*/
Dictionary<int, string> ents = entsDb.ToDictionary(k => k.id, v => v.name);
return Ok(ents);
}
然后在消费者中,我可以捕获异常并访问消息等。消费者请求:
using (var client = new HttpClient()) {
client.BaseAddress = new Uri(BaseAddress);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + Token.Access_Token);
HttpResponseMessage response = await client.GetAsync("Api/GetEntities/");
if (response.IsSuccessStatusCode) {
Dictionary<int, string> listEnts = await response.Content.ReadAsAsync<Dictionary<int, string>>();
return listEnts;
}
else {
var s = response.Content.ReadAsStringAsync();
s.Wait();
throw new Exception("An error ocurred. Server response: "+s.Result);
}
}
在上面的代码中,如果我取消注释异常块(在控制器操作方法中),它会按预期工作,并且消费者会收到异常并可以访问其消息等。
这在开发中工作正常,但是当我将 mvc/webapi 项目部署到生产服务器时,每当出现错误时,我不会收到我的异常,而是收到一条消息“页面无法显示,因为发生了内部服务器错误"
我猜这是因为 web.Release.config 配置改变了生产服务器上的“调试”开关,在 Web.Release.config 中有这一行:
<compilation xdt:Transform="RemoveAttributes(debug)"/>
所以使用这种配置,在开发中它会显示详细的错误,但在生产中它会显示一般错误。
但我不知道如何解决它。在生产服务器中针对 mvc 请求而不是针对 WebApi 请求时,有什么方法可以使其返回一般错误?顺便说一句,这真的是处理 WebApi 错误的正确方法吗?
**更新:** 好吧,显然我的猜测是无效的。我已经重新部署它,删除了 web.release.config 中的那一行,它也是一样的。另外,如果我在 localhost 但在发布模式下运行 webapi,它可以工作。所以它只是在服务器上不起作用。也许一些IIS参数或什么?
解决方案
好的,我终于找到了错误,它在web.config中。我把它放在这里以防它对某人有帮助...
关注这篇文章 是否可以在 MVC 站点而不是 Web API 中使用自定义错误页面?
在我的 web.config 中,我添加了这样的自定义错误页面:
<httpErrors existingResponse="Replace" defaultResponseMode="ExecuteURL" defaultPath="/Error/Index" errorMode="Custom">
<remove statusCode="404"/>
<remove statusCode="400"/>
<error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound" />
<error statusCode="400" responseMode="ExecuteURL" path="/Error/Forbidden" />
</httpErrors>
然后我有这个块,以便 api 调用忽略自定义错误页面并返回原始错误,如阅读here
<location path="Api">
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<httpErrors errorMode="DetailedLocalOnly" existingResponse="PassThrough" >
<clear/>
</httpErrors>
</system.webServer>
</location>
我只需要删除线路<clear/>
,现在一切正常。
推荐阅读
- html - 问题是页脚位于弹性项目的中间并且没有设置在底部
- php - for循环php时非法字符串偏移'id'
- java - 使用springboot将用户保存到h2时出错
- asp.net - 将 WebApi 从 Angular 分离到两个不同的项目
- python - Pyinstaller 无法导入模块 __PyInstaller_hooks_0_IPython
- javascript - 为什么 plupload.com PHP 照片上传器组件无法处理非常大的上传(数百个子文件夹中的数千个文件)?
- c# - 使用 GhostScript.net 将 PDF 转换为文本,尝试将文本发送到匿名管道而不是将其写入磁盘时出现错误
- php - echo "string" 时出现奇怪的结果。功能()
- javascript - 带有下一个按钮的 Django & Js 问题滑块出现在最后一个问题上
- javascript - 将逻辑应用于这个简单的井字游戏