C# 位于ASP.NET MVC顶部,显示错误
我们正在现有的asp.net c#MVC应用程序上安装一个角度前端。在服务器代码中,我们广泛使用自定义异常来返回业务规则错误C# 位于ASP.NET MVC顶部,显示错误,c#,asp.net-mvc,angularjs,C#,Asp.net Mvc,Angularjs,我们正在现有的asp.net c#MVC应用程序上安装一个角度前端。在服务器代码中,我们广泛使用自定义异常来返回业务规则错误 有没有最佳实践或最灵活的方法来处理mvc控制器或webApi控制器上的异常(实际上是从业务层弹出的),并将其传递到angular并在“用户错误”弹出窗口中显示?人们是如何解决这个问题的?通常,我一直在我们的WEB API中做这类事情,返回正确的状态代码是关键,当然,对于您想要使用的许多前端框架中的哪一个,这是完全不可知的 public IHttpActionResult
有没有最佳实践或最灵活的方法来处理mvc控制器或webApi控制器上的异常(实际上是从业务层弹出的),并将其传递到angular并在“用户错误”弹出窗口中显示?人们是如何解决这个问题的?通常,我一直在我们的WEB API中做这类事情,返回正确的状态代码是关键,当然,对于您想要使用的许多前端框架中的哪一个,这是完全不可知的
public IHttpActionResult Get(DateTime? updatesAfter = null)
{
try
{
// Do something here.
return this.Ok(result);
}
catch (Exception ex) // Be more specific if you like...
{
return this.InternalServerError(ex);
throw;
}
}
现在随WebAPIv2ApicController提供的帮助器方法非常好
this.BadRequest()
this.InternalServerError()
this.Ok()
this.Unauthorized()
this.StatusCode()
this.NotFound()
其中一些(如InternalServerError)允许您将异常或消息(或仅仅是对象)作为参数传递
通常,与任何前端框架或库一样,在初始化对API方法的ajax调用时,您可以提供一个失败或错误回调,在返回错误状态代码的情况下,将调用该回调。对于我的API控制器,我返回
HttpResponseMessage
。请看我下面的例子。我希望这有帮助
在响应消息中,您还可以将对象传回前端
WEB API
// Get all
[HttpGet]
public HttpResponseMessage Get()
{
try
{
return Request.CreateResponse(HttpStatusCode.OK, myObject);
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Error Message");
}
}
角度JS
// Get Request on Page Load
$http({
url: '/api/department/',
method: 'GET',
}).success(function (data) {
$scope.departments = data;
}).error(function (error) {
$scope.error = error;
});
HTML
<div class="alert alert-danger animate-show" role="alert" ng-show="error != null">{{ error }} </div>
<div class="alert alert-success animate-show" role="alert" ng-show="success != null">{{ success }}</div>
{{error}
{{success}}
我们刚刚完成了一个带有角度前端的大型MVC应用程序
我们只是让错误流动,例如任何网页只是得到一个错误,但没有堆栈跟踪(不是黄色屏幕,尼斯错误有***,但在你的主页等)
Web API调用只返回正确的HTTP状态。如果您愿意,它们可以包括一些细节
但是,您不想丢失这些错误,所以我们只安装了带有
Install-Package elmah
而且,它只是起作用,错误只会出现在日志中,用户会被告知某些东西不起作用等等。。不需要额外的工作
为了使我们的UI更好,我们做了以下几点,例如
未处理的错误
MVC页面
只要让MVC前端完成它的工作,它就会以一种很好的方式告诉用户出了什么问题
角度web调用
在.error函数中,向用户发出警报,例如
}).error(function (data, status, headers, config) {
$scope.addAlert('danger', 'Error deleting autosave details');
}
如果您不希望由于覆盖错误而丢失错误,请让错误堆叠。addAlert只写入前端绑定到的数据数组
已处理错误
如果您正在处理它们,那么您已经管理了发生的事情,但是要记录这些
MVC
如果您只想记录它们,elmah
API对此有一个调用
ErrorSignal.FromCurrentContext().Raise(exception );
如果您使用的是错误属性,则可以使用此属性
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new ElmahHandledErrorLoggerFilter());
filters.Add(new HandleErrorAttribute());
}
}
public class ElmahHandledErrorLoggerFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
// Log only handled exceptions, because all other will be caught by ELMAH anyway.
if (context.ExceptionHandled)
ErrorSignal.FromCurrentContext().Raise(context.Exception);
}
}
另外,对于ELMAH框架签出的一般日志记录,其他人已经给出了很好的答案,但我想详细介绍一下我的方法,因为我想它将用更多细节覆盖两端(前端和服务器) 下面是我在WebAPI+AngularJS应用程序中处理错误和异常的完整方法 第一步。服务器端的WebApi控制器 我有一个特定的DTO,用于向客户机传达验证错误,因为我认为它们不同于
Exception
s。异常将导致500错误,其中验证结果将导致400(错误请求)错误
下面是我的ApiValidationResult
类:
public class ApiValidationResult
{
public List<ApiValidationError> Errors { get; set; }
public static ApiValidationResult Failure(string errorKey)
{
return new ApiValidationResult {Errors = new List<ApiValidationError> {new ApiValidationError(errorKey)}};
}
// You can add a bunch of utility methods here
}
public class ApiValidationError
{
public ApiValidationError()
{
}
public ApiValidationError(string errorKey)
{
ErrorKey = errorKey;
}
// More utility constructors here
public string PropertyPath { get; set; }
public string ErrorKey { get; set; }
public List<string> ErrorParameters { get; set; }
}
它使用我专门为此创建的自定义IHttpActionResult
:
public class ValidationErrorResult : NegotiatedContentResult<ApiValidationResult>
{
public ValidationErrorResult(ApiValidationResult content, IContentNegotiator contentNegotiator, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)
: base(HttpStatusCode.BadRequest, content, contentNegotiator, request, formatters)
{
}
public ValidationErrorResult(ApiValidationResult content, ApiController controller)
: base(HttpStatusCode.BadRequest, content, controller)
{
}
}
第二步。处理意外异常
正如我所说的,我认为只有真正的未处理的异常
s才会导致500(内部服务器错误)响应
此类未经处理的异常由WebApi自动转换为500结果。我唯一需要做的就是把它们记录下来。因此,我创建了一个IEExceptionLogger
接口的实现,并按如下方式注册它:
GlobalConfiguration.Configuration.Services.Add(typeof(IExceptionLogger), new UnhandledExceptionLogger());
appModule.config([
'$httpProvider',
($httpProvider: ng.IHttpProvider) => {
$httpProvider.interceptors.push('errorsHttpInterceptor');
}
]);
$http({ method: methodType, url: endpoint })
.then(function (response) {
response.status; //gets you the HttpStatusCode to play with
response.data; //gets you the ReponseContent section
}, function (response) {
response.status; //gets you the HttpStatusCode
response.data; //gets you the ReponseContent section
});
第三步。在客户端截取并显示错误
AngularJS允许拦截从$HTTP
服务发送的所有HTTP调用。我用它来集中所有的消息弹出窗口。这是我的拦截器代码:
appModule.factory("errorsHttpInterceptor", [
"$q", "$rootScope", "$injector",
($q: ng.IQService, $rootScope: IAppRootScopeService, $injector) => {
return {
'responseError': rejection => {
// Maybe put the error in $rootScope and show it in UI
// Maybe use a popup
// Maybe use a 'toast'
var toastr = $injector.get('toastr');
toastr.error(...);
return $q.reject(rejection);
}
};
}
]);
您可以在拦截器中执行各种操作,例如记录调试消息,或应用键显示错误代码的字符串转换。您还可以区分500和400个错误,并显示不同类型的错误消息
我使用toastr库,我认为它显示了一个很好的UI,在API级别非常方便
最后,我注册拦截器如下:
GlobalConfiguration.Configuration.Services.Add(typeof(IExceptionLogger), new UnhandledExceptionLogger());
appModule.config([
'$httpProvider',
($httpProvider: ng.IHttpProvider) => {
$httpProvider.interceptors.push('errorsHttpInterceptor');
}
]);
$http({ method: methodType, url: endpoint })
.then(function (response) {
response.status; //gets you the HttpStatusCode to play with
response.data; //gets you the ReponseContent section
}, function (response) {
response.status; //gets you the HttpStatusCode
response.data; //gets you the ReponseContent section
});
语法是用TypeScript编写的,它与JavaScript非常相似,我相信您可以理解它的含义。另一种方法是返回内容 以下是我如何做到这一点(端到端)。从我的API:
return Content(HttpStatusCode.<statuscode>, "ResponseContent: " + "my_custom_error");
有关HttpStatusCodes的更多详细信息,请参阅
在角度代码中,我是这样读的:
GlobalConfiguration.Configuration.Services.Add(typeof(IExceptionLogger), new UnhandledExceptionLogger());
appModule.config([
'$httpProvider',
($httpProvider: ng.IHttpProvider) => {
$httpProvider.interceptors.push('errorsHttpInterceptor');
}
]);
$http({ method: methodType, url: endpoint })
.then(function (response) {
response.status; //gets you the HttpStatusCode to play with
response.data; //gets you the ReponseContent section
}, function (response) {
response.status; //gets you the HttpStatusCode
response.data; //gets you the ReponseContent section
});
确保在进行http调用时,responseType
未设置为“JSON”。因为API返回的数据在此阶段不是JSON格式
从中,响应对象具有以下属性:
数据{string | Object}–使用
变换函数
状态–{number}–响应的HTTP状态代码
headers–{function([headerName])}–Header getter函数
config–{Object}–用于
生成请求
statusText–{string}–响应的HTTP状态文本
因为这不是特定于代码的,所以最好在程序员堆栈中使用ExchangeOuter,而黄色死亡屏幕的替代方案是带有抱歉消息的javascript警报。这是个例外,不应该发生,所以我们认为没关系。但是标准错误是根据情况来处理的。感谢您的回复,在Angular si上如何处理这些错误