用vs2017建立一個ASP.NET Core Web應用程式並選擇MVC框架,自動生成了 Startup的類,並配置了錯誤處理方式: if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExcept ...
用vs2017建立一個ASP.NET Core Web應用程式並選擇MVC框架,自動生成了 Startup的類,並配置了錯誤處理方式:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
簡單講:
- 開發環境,直接在當前頁面顯示錯誤
- 生產環境:跳轉到 /Home/Error頁面
而在實際開發和生產過程中,我們需要:
- 開發環境,我們有時候會用到ajax調用,需要快速定位錯誤(比如alert(....))
- 生產環境:我們需要把錯誤信息保存起來,當然ajax調用的時候不能直接alert一個/Home/Error的html給用戶
如下麵的代碼:
Action:
public IActionResult Edit(int id = 0)
{
if (id == 0) //模擬用戶不能修改該Id的內容
return NotFound("沒有操作許可權");
if (id == 1) //模擬發生異常了
throw new Exception("錯誤:error desc");
return View();
}
/// <summary>
/// ajax調用
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPost]
public IActionResult Save(int id = 0)
{
if (id == 0) //模擬用戶不能修改該Id的內容
return NotFound("沒有操作許可權");
if (id == 1) //模擬發生異常了
throw new Exception("錯誤:error desc");
return Content(id + DateTime.Now.ToString());
}
View(Edit.cshtml)
<div class="text-center">
id:
<input type="text" id="TId" />
<input type="button" value="Save" id="BSave" />
<span id="SResult"></span>
</div>
@section scripts
{
<script>
$(function () {
$("#BSave").click(function () {
$.ajax({
type: "post",
url: "@Url.Action("Save")",
data: { id: $("#TId").val() },
success: function (ret) {
$("#SResult").html(ret);
},
error: function (XMLHttpRequest) {
if (XMLHttpRequest.responseText != "") {
alert(XMLHttpRequest.responseText);
}
else
alert(XMLHttpRequest.status );
}
});
});
});
</script>
}
Ctrl+F5##運行:
好,我們需要保存錯誤信息,並更友好的提示ajax調用錯誤。
1.添加一個類
public class FilterException : IExceptionFilter
{
private readonly YKDbContext db;
private readonly IHostingEnvironment _Env;
public FilterException(YKDbContext dbContext, IHostingEnvironment env)
{
db = dbContext;
_Env = env;
}
public void OnException(ExceptionContext context)
{
if (_Env.IsDevelopment())
{
if (context.HttpContext.Request.Headers["x-requested-with"] == "XMLHttpRequest")
{
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
string msg = context.Exception.Message;
Exception ex = context.Exception;
while (ex.InnerException != null)
{
ex = ex.InnerException;
msg += ex.Message;
}
context.Result = new JsonResult(msg);
context.ExceptionHandled = true; // 表明異常已處理,客戶端可得到正常返回
}
}
else
{
string msg = context.Exception.Message;
Exception ex = context.Exception;
while (ex.InnerException != null)
{
ex = ex.InnerException;
msg += ex.Message;
}
//存入db
if (context.HttpContext.Request.Headers["x-requested-with"] == "XMLHttpRequest")
{
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Result = new JsonResult("出錯了!已經將錯誤信息發送給開發人員,開發人員將儘快處理。");
context.ExceptionHandled = true;
}
}
}
}
2.配置服務
在類Startup
的方法ConfigureServices
中修改
services.AddMvc(options =>
{
options.Filters.Add<FilterException>();
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
依然按##Ctrl+F5##運行:
是我們想要的結果吧?!
附:Filter裡面如何判斷Controller
是否有ApiController
屬性
bool isApi = context.Filters.Any(ii => ii.GetType().Name == "ApiControllerAttribute");