mirror of https://github.com/abpframework/abp.git
committed by
GitHub
9 changed files with 207 additions and 161 deletions
@ -0,0 +1,14 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared |
||||
|
{ |
||||
|
public class AbpErrorPageOptions |
||||
|
{ |
||||
|
public readonly IDictionary<string, string> ErrorViewUrls; |
||||
|
|
||||
|
public AbpErrorPageOptions() |
||||
|
{ |
||||
|
ErrorViewUrls = new Dictionary<string, string>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,70 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Localization.Resources.AbpUi; |
||||
|
using Microsoft.AspNetCore.Diagnostics; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Microsoft.Extensions.Localization; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.AspNetCore.ExceptionHandling; |
||||
|
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Views.Error; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Controllers |
||||
|
{ |
||||
|
public class ErrorController : AbpController |
||||
|
{ |
||||
|
private readonly IExceptionToErrorInfoConverter _errorInfoConverter; |
||||
|
private readonly IHttpExceptionStatusCodeFinder _statusCodeFinder; |
||||
|
private readonly IStringLocalizer<AbpUiResource> _localizer; |
||||
|
private readonly AbpErrorPageOptions _abpErrorPageOptions; |
||||
|
|
||||
|
public ErrorController( |
||||
|
IExceptionToErrorInfoConverter exceptionToErrorInfoConverter, |
||||
|
IHttpExceptionStatusCodeFinder httpExceptionStatusCodeFinder, |
||||
|
IOptions<AbpErrorPageOptions> abpErrorPageOptions, |
||||
|
IStringLocalizer<AbpUiResource> localizer) |
||||
|
{ |
||||
|
_errorInfoConverter = exceptionToErrorInfoConverter; |
||||
|
_statusCodeFinder = httpExceptionStatusCodeFinder; |
||||
|
_localizer = localizer; |
||||
|
_abpErrorPageOptions = abpErrorPageOptions.Value; |
||||
|
} |
||||
|
|
||||
|
public IActionResult Index(int httpStatusCode) |
||||
|
{ |
||||
|
var exHandlerFeature = HttpContext.Features.Get<IExceptionHandlerFeature>(); |
||||
|
|
||||
|
var exception = exHandlerFeature != null |
||||
|
? exHandlerFeature.Error |
||||
|
: new Exception(_localizer["UnhandledException"]); |
||||
|
|
||||
|
var errorInfo = _errorInfoConverter.Convert(exception); |
||||
|
|
||||
|
if (httpStatusCode == 0) |
||||
|
{ |
||||
|
httpStatusCode = (int)_statusCodeFinder.GetStatusCode(HttpContext, exception); |
||||
|
} |
||||
|
|
||||
|
HttpContext.Response.StatusCode = httpStatusCode; |
||||
|
|
||||
|
var page = GetErrorPageUrl(httpStatusCode); |
||||
|
|
||||
|
return View(page, new AbpErrorPageModel |
||||
|
{ |
||||
|
ErrorInfo = errorInfo, |
||||
|
HttpStatusCode = httpStatusCode |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private string GetErrorPageUrl(int statusCode) |
||||
|
{ |
||||
|
var page = _abpErrorPageOptions.ErrorViewUrls.GetOrDefault(statusCode.ToString()); |
||||
|
|
||||
|
if (string.IsNullOrWhiteSpace(page)) |
||||
|
{ |
||||
|
return "~/Pages/Error/Default.cshtml"; |
||||
|
} |
||||
|
|
||||
|
return page; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,41 +0,0 @@ |
|||||
@page |
|
||||
@using System.Linq |
|
||||
@using System.Collections.Generic |
|
||||
@using Localization.Resources.AbpUi |
|
||||
@using Microsoft.AspNetCore.Mvc.Localization |
|
||||
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Error |
|
||||
@model IndexModel |
|
||||
@inject IHtmlLocalizer<AbpUiResource> L |
|
||||
@{ |
|
||||
var errorMessage = Model.ErrorInfo.Message; |
|
||||
var errorDetails = Model.ErrorInfo.Details; |
|
||||
if (errorDetails.IsNullOrEmpty()) |
|
||||
{ |
|
||||
errorDetails = errorMessage; |
|
||||
errorMessage = L["Error"].Value + "!"; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
<h1> |
|
||||
[@Model.HttpStatusCode] @errorMessage |
|
||||
</h1> |
|
||||
|
|
||||
<div> |
|
||||
<p> |
|
||||
@errorDetails |
|
||||
</p> |
|
||||
<p> |
|
||||
@if (!Model.ErrorInfo.ValidationErrors.IsNullOrEmpty()) |
|
||||
{ |
|
||||
foreach (var validationError in Model.ErrorInfo.ValidationErrors) |
|
||||
{ |
|
||||
<text>* </text>@(validationError.Message) |
|
||||
if (validationError.Members != null && validationError.Members.Any()) |
|
||||
{ |
|
||||
<text>(@string.Join(", ", validationError.Members))</text> |
|
||||
} |
|
||||
<br /> |
|
||||
} |
|
||||
} |
|
||||
</p> |
|
||||
</div> |
|
||||
@ -1,69 +0,0 @@ |
|||||
using System; |
|
||||
using Microsoft.AspNetCore.Diagnostics; |
|
||||
using Microsoft.AspNetCore.Mvc; |
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages; |
|
||||
using Volo.Abp.AspNetCore.ExceptionHandling; |
|
||||
using Volo.Abp.Http; |
|
||||
|
|
||||
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Error |
|
||||
{ |
|
||||
public class IndexModel : PageModel |
|
||||
{ |
|
||||
public RemoteServiceErrorInfo ErrorInfo { get; set; } |
|
||||
|
|
||||
[BindProperty(SupportsGet = true)] |
|
||||
public int HttpStatusCode { get; set; } |
|
||||
|
|
||||
private readonly IExceptionToErrorInfoConverter _errorInfoConverter; |
|
||||
private readonly IHttpExceptionStatusCodeFinder _statusCodeFinder; |
|
||||
|
|
||||
public IndexModel(IExceptionToErrorInfoConverter errorInfoConverter, IHttpExceptionStatusCodeFinder statusCodeFinder) |
|
||||
{ |
|
||||
_errorInfoConverter = errorInfoConverter; |
|
||||
_statusCodeFinder = statusCodeFinder; |
|
||||
} |
|
||||
|
|
||||
public void OnGet() |
|
||||
{ |
|
||||
HandleError(); |
|
||||
} |
|
||||
|
|
||||
public void OnPost() |
|
||||
{ |
|
||||
HandleError(); |
|
||||
} |
|
||||
|
|
||||
public void OnPut() |
|
||||
{ |
|
||||
HandleError(); |
|
||||
} |
|
||||
|
|
||||
public void OnDelete() |
|
||||
{ |
|
||||
HandleError(); |
|
||||
} |
|
||||
|
|
||||
public void OnPatch() |
|
||||
{ |
|
||||
HandleError(); |
|
||||
} |
|
||||
|
|
||||
private void HandleError() |
|
||||
{ |
|
||||
var exHandlerFeature = HttpContext.Features.Get<IExceptionHandlerFeature>(); |
|
||||
|
|
||||
var exception = exHandlerFeature != null |
|
||||
? exHandlerFeature.Error |
|
||||
: new Exception("Unhandled exception!"); //TODO: Localize?
|
|
||||
|
|
||||
ErrorInfo = _errorInfoConverter.Convert(exception); |
|
||||
|
|
||||
if (HttpStatusCode == 0) |
|
||||
{ |
|
||||
HttpStatusCode = (int)_statusCodeFinder.GetStatusCode(HttpContext, exception); |
|
||||
} |
|
||||
|
|
||||
HttpContext.Response.StatusCode = HttpStatusCode; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,11 @@ |
|||||
|
using Volo.Abp.Http; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Views.Error |
||||
|
{ |
||||
|
public class AbpErrorPageModel |
||||
|
{ |
||||
|
public RemoteServiceErrorInfo ErrorInfo { get; set; } |
||||
|
|
||||
|
public int HttpStatusCode { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,40 @@ |
|||||
|
@using System.Linq |
||||
|
@using System.Collections.Generic |
||||
|
@using Localization.Resources.AbpUi |
||||
|
@using Microsoft.AspNetCore.Mvc.Localization |
||||
|
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Error |
||||
|
@model AbpErrorPageModel |
||||
|
@inject IHtmlLocalizer<AbpUiResource> L |
||||
|
@{ |
||||
|
var errorMessage = Model.ErrorInfo.Message; |
||||
|
var errorDetails = Model.ErrorInfo.Details; |
||||
|
if (errorDetails.IsNullOrEmpty()) |
||||
|
{ |
||||
|
errorDetails = errorMessage; |
||||
|
errorMessage = L["Error"].Value + "!"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
<h1> |
||||
|
[@Model.HttpStatusCode] @errorMessage |
||||
|
</h1> |
||||
|
|
||||
|
<div> |
||||
|
<p> |
||||
|
@errorDetails |
||||
|
</p> |
||||
|
<p> |
||||
|
@if (!Model.ErrorInfo.ValidationErrors.IsNullOrEmpty()) |
||||
|
{ |
||||
|
foreach (var validationError in Model.ErrorInfo.ValidationErrors) |
||||
|
{ |
||||
|
<text>* </text>@(validationError.Message) |
||||
|
if (validationError.Members != null && validationError.Members.Any()) |
||||
|
{ |
||||
|
<text>(@string.Join(", ", validationError.Members))</text> |
||||
|
} |
||||
|
<br /> |
||||
|
} |
||||
|
} |
||||
|
</p> |
||||
|
</div> |
||||
@ -1,51 +1,58 @@ |
|||||
{ |
{ |
||||
"culture": "zh-Hans", |
"culture": "zh-Hans", |
||||
"texts": { |
"texts": { |
||||
"InternalServerErrorMessage": "对不起,在处理你的请求期间,产生了一个服务器内部错误!", |
"InternalServerErrorMessage": "对不起,在处理你的请求期间,产生了一个服务器内部错误!", |
||||
"ValidationErrorMessage": "你的请求无效!", |
"ValidationErrorMessage": "你的请求无效!", |
||||
"ValidationNarrativeErrorMessageTitle": "验证时发现以下错误.", |
"ValidationNarrativeErrorMessageTitle": "验证时发现以下错误.", |
||||
"DefaultErrorMessage": "发生错误!", |
"DefaultErrorMessage": "发生错误!", |
||||
"DefaultErrorMessageDetail": "服务器未发送错误的详细信息.", |
"DefaultErrorMessageDetail": "服务器未发送错误的详细信息.", |
||||
"DefaultErrorMessage401": "未通过身份验证!", |
"DefaultErrorMessage401": "未通过身份验证!", |
||||
"DefaultErrorMessage401Detail": "你需要进行身份认证(登录)后再执行此操作.", |
"DefaultErrorMessage401Detail": "你需要进行身份认证(登录)后再执行此操作.", |
||||
"DefaultErrorMessage403": "你没有权限!", |
"DefaultErrorMessage403": "你没有权限!", |
||||
"DefaultErrorMessage403Detail": "你不能执行此操作!", |
"DefaultErrorMessage403Detail": "你不能执行此操作!", |
||||
"DefaultErrorMessage404": "未找到资源!", |
"DefaultErrorMessage404": "未找到资源!", |
||||
"DefaultErrorMessage404Detail": "未在服务中找到请求的资源!", |
"DefaultErrorMessage404Detail": "未在服务中找到请求的资源!", |
||||
"EntityNotFoundErrorMessage": "实体 {0} 不存在,id = {1}!", |
"EntityNotFoundErrorMessage": "实体 {0} 不存在,id = {1}!", |
||||
"Error": "错误", |
"Error": "错误", |
||||
"AreYouSure": "你确定吗?", |
"AreYouSure": "你确定吗?", |
||||
"Cancel": "取消", |
"Cancel": "取消", |
||||
"Yes": "是", |
"Yes": "是", |
||||
"No": "否", |
"No": "否", |
||||
"Close": "关闭", |
"Close": "关闭", |
||||
"Save": "保存", |
"Save": "保存", |
||||
"SavingWithThreeDot": "保存中...", |
"SavingWithThreeDot": "保存中...", |
||||
"Actions": "操作", |
"Actions": "操作", |
||||
"Delete": "删除", |
"Delete": "删除", |
||||
"Edit": "编辑", |
"Edit": "编辑", |
||||
"Refresh": "刷新", |
"Refresh": "刷新", |
||||
"ProcessingWithThreeDot": "处理中...", |
"ProcessingWithThreeDot": "处理中...", |
||||
"LoadingWithThreeDot": "加载中...", |
"LoadingWithThreeDot": "加载中...", |
||||
"Welcome": "欢迎", |
"Welcome": "欢迎", |
||||
"Login": "登录", |
"Login": "登录", |
||||
"Register": "注册", |
"Register": "注册", |
||||
"Logout": "注销", |
"Logout": "注销", |
||||
"Submit": "提交", |
"Submit": "提交", |
||||
"Back": "返回", |
"Back": "返回", |
||||
"PagerSearch": "搜索", |
"PagerSearch": "搜索", |
||||
"PagerNext": "下一页", |
"PagerNext": "下一页", |
||||
"PagerPrevious": "上一页", |
"PagerPrevious": "上一页", |
||||
"PagerFirst": "首页", |
"PagerFirst": "首页", |
||||
"PagerLast": "尾页", |
"PagerLast": "尾页", |
||||
"PagerInfo": "显示 _TOTAL_ 个条目中的 _START_ 到 _END_ 个.", |
"PagerInfo": "显示 _TOTAL_ 个条目中的 _START_ 到 _END_ 个.", |
||||
"PagerInfoEmpty": "显示0个条目中的0到0", |
"PagerInfoEmpty": "显示0个条目中的0到0", |
||||
"PagerInfoFiltered": "(从 _MAX_ 总条目中过滤掉)", |
"PagerInfoFiltered": "(从 _MAX_ 总条目中过滤掉)", |
||||
"NoDataAvailableInDatatable": "表中没有数据", |
"NoDataAvailableInDatatable": "表中没有数据", |
||||
"PagerShowMenuEntries": "显示 _MENU_ 实体", |
"PagerShowMenuEntries": "显示 _MENU_ 实体", |
||||
"DatatableActionDropdownDefaultText": "操作", |
"DatatableActionDropdownDefaultText": "操作", |
||||
"ChangePassword": "修改密码", |
"ChangePassword": "修改密码", |
||||
"PersonalInfo": "个人信息", |
"PersonalInfo": "个人信息", |
||||
"AreYouSureYouWantToCancelEditingWarningMessage": "你有未保存的更改." |
"AreYouSureYouWantToCancelEditingWarningMessage": "你有未保存的更改.", |
||||
} |
"UnhandledException": "未处理的异常!", |
||||
|
"401Message": "未授权", |
||||
|
"403Message": "禁止访问", |
||||
|
"404Message": "网页未找到", |
||||
|
"500Message": "内部服务器错误", |
||||
|
"GoHomePage": "返回主页", |
||||
|
"GoBack": "返回" |
||||
} |
} |
||||
|
} |
||||
Loading…
Reference in new issue