一.过滤器
1.如果一个web程序同时包含MVC和WebAPI,现在需要给WebAPI部分单独添加一个接口验证过滤器IActionFilter,注册全局过滤器的方式为:
services.AddControllers(o => { // 全局过滤器 o.Filters.Add(typeof(AccessControlFilter));
//增加全局异常过滤器
o.Filters.Add(typeof(GlobalExceptionsFilter)); })
但是这样做会带来一个问题,那就是MVC部分控制器也会受影响,解决方法是实现ModelConvertion,常见的Convertion有
IApplicationModelConvention IControllerModelConvention IActionModelConvention IParameterModelConvention IPageRouteModelConvention
1.1-> 实现IControllerModelConvention
1.2 ->实现IApplicationModelConvention
那么如何把这个约定注册到应用中呢?在Microsoft.AspNetCore.MVC.MvcOptions中提供了Convertions属性:public IList<IApplicationModelConvention> Conventions;通过操作它就能把自定义约定注入进去
services.AddMvc(options => { options.Filters.Add(typeof(GlobalExceptionFilter)); options.Conventions.Add(new ApiControllerAuthorizeConvention()); })
2..NetCore中AddMvc/AddMvcCore/AddControllers区别
service.AddMvc()包含的功能最为齐全,如下图
2.全局异常过滤器:实现IExceptionFilter
using Hos.ScheduleMaster.Core; using Hos.ScheduleMaster.Core.Log; using Hos.ScheduleMaster.Web.Extension; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Hos.ScheduleMaster.Web.Filters { public class GlobalExceptionFilter : IExceptionFilter { private readonly IWebHostEnvironment _env; public GlobalExceptionFilter(IWebHostEnvironment env) { _env = env; } public void OnException(ExceptionContext context) { LogHelper.Error(context.HttpContext.Request.Path, context.Exception); if (context.HttpContext.Request.IsAjaxRequest()) { var accept = context.HttpContext.Request.Headers["Accept"].FirstOrDefault(); if (accept.Contains("application/json")) { context.Result = new JsonNetResult() { Data = new { Success = false, Message = "服务出现异常请稍后再试!" } }; } else { context.Result = new JavaScriptResult("alert('服务出现异常请稍后再试!')"); }
context.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.ServiceUnavailable; } else { context.Result = new RedirectResult("/Static/Page404"); } context.ExceptionHandled = true; } } }
针对web中包含MVC的页面请求,需要判断请求方式是否是ajax请求,代码如下
/// <summary> /// 判断是否异步请求 /// </summary> /// <param name="request"></param> /// <returns></returns> public static bool IsAjaxRequest(this Microsoft.AspNetCore.Http.HttpRequest request) { bool isAjax = false; var xreq = request.Headers.ContainsKey("x-requested-with"); if (xreq) { isAjax = request.Headers["x-requested-with"] == "XMLHttpRequest"; } return isAjax; }
JsonNetResult类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; namespace Hos.ScheduleMaster.Web.Extension { /// <summary> /// 用json.net重写一个ControllerResult /// </summary> public class JsonNetResult : ActionResult { // 构造函数 public JsonNetResult() { Settings = new JsonSerializerSettings { //忽略掉循环引用 ReferenceLoopHandling = ReferenceLoopHandling.Ignore, //设置时间格式 DateFormatString = "yyyy-MM-dd HH:mm:ss", //不使用驼峰样式的key ContractResolver = new DefaultContractResolver() }; } public override void ExecuteResult(ActionContext context) { if (context == null) { throw new ArgumentNullException("ActionContext"); } HttpResponse response = context.HttpContext.Response; response.ContentType = "application/json"; if (this.Data != null) { response.WriteAsync(JsonConvert.SerializeObject(Data, Settings)); } } public object Data { get; set; } public JsonSerializerSettings Settings { get; private set; } } /// <summary> /// 基于JsonNetResult直接在controller中返回json的扩展方法 /// </summary> public static class JsonNetResultExtension { public static JsonNetResult JsonNet(this Controller controller, bool success, string msg = "", string url = "", object data = null) { return JsonNet(new { Success = success, Message = msg, Url = url, Data = data }); } public static JsonNetResult JsonNet(this Controller controller, object data) { return JsonNet(data); } /// <summary> /// 创建JsonNetResult对象,输出json数据到客户端 /// </summary> /// <param name="data"></param> /// <param name="contentType"></param> /// <param name="encoding"></param> /// <param name="behavior"></param> /// <returns></returns> private static JsonNetResult JsonNet(object data) { return new JsonNetResult() { Data = data }; } } }
JavaScriptResult类:
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Hos.ScheduleMaster.Web.Extension { public class JavaScriptResult : ActionResult { public string Scripts; public JavaScriptResult() { } public JavaScriptResult(string scrpits) { this.Scripts = scrpits; } public override void ExecuteResult(ActionContext context) { if (context == null) { throw new ArgumentNullException("ActionContext"); } HttpResponse response = context.HttpContext.Response; response.ContentType = "application/javascript"; response.WriteAsync(Scripts); } } public static class JavaScriptResultExtension { public static JavaScriptResult JavaScript(this Controller controller, string scripts) { return new JavaScriptResult(scripts); } } }