public static void Start()
{
logger.Debug("Startup WebAPI...");
SwaggerConfig.Register();
GlobalConfiguration.Configure(WebApiConfig.Register);
。。。
public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.MapHttpAttributeRoutes(); config.Filters.Add(new CustomExceptionFilterAttribute()); config.Filters.Add(new ModelStateValidationFilterAttribute()); } }
CustomExceptionFilterAttribute :
using System; using System.Linq; using System.Net.Http; using System.Web.Http; using System.Web.Http.Filters; using GlobalPaymentsPortalWebApi.Exceptions; using NLog; namespace TestWebApi.Filters { public class CustomExceptionFilterAttribute : ExceptionFilterAttribute { readonly ILogger logger = LogManager.GetCurrentClassLogger(); public override void OnException(HttpActionExecutedContext actionExecutedContext) { var requestInfo = actionExecutedContext.Request.Method.Method + " " + actionExecutedContext.Request.RequestUri.PathAndQuery; if (actionExecutedContext.Exception is CustomException customException) { var res = new CustomErrorResponse(((CustomException)actionExecutedContext.Exception).Code, ((CustomException)actionExecutedContext.Exception).Error); HttpResponseMessage httpResponse = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest); httpResponse.Content = new ObjectContent<CustomErrorResponse>(res, GlobalConfiguration.Configuration.Formatters.JsonFormatter); actionExecutedContext.Response = httpResponse; string modelErrors = string.Empty; if (!actionExecutedContext.ActionContext.ModelState.IsValid) { modelErrors = actionExecutedContext.ActionContext.ModelState.SelectMany(state => state.Value.Errors).Aggregate("", (current, error) => current + (error.ErrorMessage + " ")); } if (!string.IsNullOrEmpty(customException.Error)) { logger.Info("{0}: {1} -> [{2}]: {3}", customException.Code, customException.Error, requestInfo, modelErrors); } else { logger.Info("{0} -> [{1}]: {2}", customException.Code, requestInfo, modelErrors); } } else if (actionExecutedContext.Exception is NotFoundException notfoundException) { actionExecutedContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.NotFound); logger.Info("NotFound -> [{0}]", requestInfo); } else { actionExecutedContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError); logger.Error(actionExecutedContext.Exception, "{0} -> [{1}]", actionExecutedContext.Exception.Message, requestInfo); } } } }
ModelStateValidationFilterAttribute :
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web.Http.Controllers; using System.Web.Http.Filters; namespace TestWebApi.Filters { public class ModelStateValidationFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { if(!actionContext.ModelState.IsValid) { throw new CustomException(CustomError.BadRequestParameter); } base.OnActionExecuting(actionContext); } } }
CustomException :
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; namespace TestWebApi.Exceptions { public enum CustomError { Unknown = 0, BadRequestParameter, DuplicatedKey, LoginFailed, DuplicatedLoyaltyTier, DuplicatedKioskType, CancelFailed, DeployFailed } [Serializable] public class CustomException : Exception { public CustomError Code { get; } public string Error { get; } public CustomException(CustomError code, string error = null) { Code = code; Error = error; } } }
public class CustomErrorResponse { [Required] public CustomError? Code { get; set; } public string Error { get; set; } public CustomErrorResponse(CustomError code, string error = null) { Code = code; Error = error; } }