MVC中全局错误拦截记录日志,WebApi中全局错误拦截以及授权验证401,jquery cors 跨域

版权声明:本文为博主原创文章,未经博主允许不得转载,如文章对您有帮助,请页面左侧随意打赏。 https://blog.csdn.net/smartsmile2012/article/details/82751674
using Magic.Tool;
using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

//MVC中全局错误拦截
namespace Magic.Mvc
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
        }

        /// <summary>
        /// 全局错误处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Application_Error(object sender, EventArgs e)
        {
            var error = "";
            try
            {
                Exception exception = Server.GetLastError();
                error = exception != null ? exception.Message : "";
                Response.Clear();
                HttpException httpException = exception as HttpException;
                RouteData routeData = new RouteData();
                routeData.Values.Add("controller", "Error");

                if (httpException != null)
                {
                    switch (httpException.GetHttpCode())
                    {
                        case 404:
                            // Page not found.  
                            routeData.Values.Add("action", "HttpError404");
                            break;
                        case 500:
                            // Server error.  
                            routeData.Values.Add("action", "HttpError500");
                            break;
                        // Here you can handle Views to other error codes.  
                        // I choose a General error template    
                        default:
                            routeData.Values.Add("action", "General");
                            break;
                    }
                }
                // Pass exception details to the target error View.  
                routeData.Values.Add("error", exception.Message);
                // Clear the error on server.  
                Server.ClearError();
                // Call target Controller and pass the routeData.  
                IController errorController = new Controllers.ErrorController();
                errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
            }
            catch (Exception ex)
            {
                LogHelper.Log(ex.Message);
            }
            finally
            {
                LogHelper.Log("全局捕获错误 " + error);
            }

        }
    }
}
using System.Web.Mvc;

namespace Magic.Mvc.Controllers
{
    /// <summary>
    /// 统一错误处理
    /// </summary>
    public class ErrorController : Controller
    {
        public ActionResult Index(string error)
        {
            var errorTitle = "网站内部错误,请稍后再尝试";
            ViewData["Title"] = errorTitle;
            ViewData["Description"] = error;

            //return View("Index");
            return Content(errorTitle, null, System.Text.Encoding.GetEncoding("GB2312"));
        }
        public ActionResult HttpError404(string error)
        {
            var errorTitle = "HTTP 404 - 无法找到文件";
            ViewData["Title"] = errorTitle;
            ViewData["Description"] = error;

            //return View("Index");
            return Content(errorTitle, null, System.Text.Encoding.GetEncoding("GB2312"));
        }
        public ActionResult HttpError500(string error)
        {
            var errorTitle = "HTTP 500 - 内部服务器错误";
            ViewData["Title"] = errorTitle;
            ViewData["Description"] = error;

            //return View("Index");
            return Content(errorTitle, null, System.Text.Encoding.GetEncoding("GB2312"));
        }
        public ActionResult General(string error)
        {
            var errorTitle = "HTTP 发生错误";
            ViewData["Title"] = errorTitle;
            ViewData["Description"] = error;

            //return View("Index");
            return Content(errorTitle, null, System.Text.Encoding.GetEncoding("GB2312"));
        }
    }
}

下面是WebApi全局错误拦截和授权验证

using Magic.Tool;
using System;
using System.Web;
using System.Web.Http;
using System.Web.Routing;

namespace Magic.WebApi
{
    public class Global : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            GlobalConfiguration.Configure(WebApiConfig.Register); //添加
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            //注册一个自定义的全局WebApi异常过滤器
            GlobalConfiguration.Configuration.Filters.Add(new WebApiExceptionFilterAttribute());
        }

        /// <summary>
        /// 全局错误处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Application_Error(object sender, EventArgs e)
        {
            var error = "";
            var errorCode = "";
            ResultHelper obj = new ResultHelper();
            try
            {
                Exception exception = Server.GetLastError();
                error = exception != null ? exception.Message : "";
                Response.Clear();
                HttpException httpException = exception as HttpException;
                errorCode = (httpException != null) ? httpException.GetHttpCode().ToString() : "";
                // Clear the error on server.  
                Server.ClearError();
                // Call target Controller and pass the routeData. 
            }
            catch (Exception ex)
            {
                error += ex.Message;
            }
            finally
            {
                var errorMsg = string.Format("Application_Error 全局捕获错误 {0} {1}", errorCode, error);
                LogHelper.Log(errorMsg);
                //跳转至出错页面 
                Response.Write("HTTP 请求发生错误,请稍后尝试。");
                Response.Flush();
                Response.End();

            }

        }
    }
}
using System.Web.Http;
using System.Web.Http.Cors;

namespace Magic.WebApi
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            //跨域配置
            config.EnableCors(new EnableCorsAttribute("*", "*", "*"));

            //Json处理
            var json = config.Formatters.JsonFormatter;
            // 解决json序列化时的循环引用问题
            json.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
            // 干掉XML序列化器
            config.Formatters.Remove(config.Formatters.XmlFormatter);

            // Web API 路由
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            config.Filters.Add(new WebApiExceptionFilterAttribute()); //添加
        }
    }
}
using Magic.Tool;
using System.Web.Http;
using System.Web.Http.Filters;

namespace Magic.WebApi
{
    /// <summary>
    /// 异常拦截
    /// </summary>
    public class WebApiExceptionFilterAttribute : ExceptionFilterAttribute
    {
        public override void OnException(HttpActionExecutedContext actionExecutedContext)
        {
            string message = string.Format("<br>消息类型:{0}<br>消息内容:{1}<br>引发异常的方法:{2}<br>引发异常的对象:{3}"
                            , actionExecutedContext.Exception.GetType().Name
                            , actionExecutedContext.Exception.Message
                            , actionExecutedContext.Exception.TargetSite
                            , actionExecutedContext.Exception.Source);
            Magic.Tool.LogHelper.Log(message);
            ResultHelper obj = new ResultHelper();
            obj.status = false;
            obj.msg = "api发生错误 " + actionExecutedContext.Exception.Message;
            var resp = ToJson.ObjToJson(obj);
            throw new HttpResponseException(resp);
        }
    }
}
using Magic.Tool;
using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Text;

namespace Magic.WebApi
{
    public class ToJson
    {
        public static HttpResponseMessage SetResult(string error)
        {
            ResultHelper obj = new ResultHelper();
            obj.status = false;
            obj.msg = error;
            var resultObj = JsonConvert.SerializeObject(obj);
            return ObjToJson(resultObj);
        }

        public static HttpResponseMessage ObjToJson(Object obj)
        {
            String str;
            if (obj is String || obj is Char)
            {
                str = obj.ToString();
            }
            else
            {
                str = JsonConvert.SerializeObject(obj);
            }
            HttpResponseMessage result = new HttpResponseMessage
            {
                Content = new StringContent(str, Encoding.GetEncoding("UTF-8"), "application/json")
            };
            return result;
        }
    }
}
using System;
using System.Linq;
using System.Web;
using System.Web.Http;

namespace Magic.WebApi
{
    /// <summary>
    /// 权限拦截
    /// </summary>
    public class AuthFilter : AuthorizeAttribute
    {
        //重写基类的验证方式,加入我们自定义的Ticket验证
        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            //url获取token
            var content = actionContext.Request.Properties["MS_HttpContext"] as HttpContextBase;
            var token = content.Request.Headers["Token"];
            if (!string.IsNullOrEmpty(token))
            {
                //解密用户ticket,并校验用户名密码是否匹配
                if (ValidateTicket(token))
                {
                    base.IsAuthorized(actionContext);
                }
                else
                {
                    HandleUnauthorizedRequest(actionContext);
                }
            }
            //如果取不到身份验证信息,并且不允许匿名访问,则返回未验证401
            else
            {
                var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
                bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
                if (isAnonymous) base.OnAuthorization(actionContext);
                else HandleUnauthorizedRequest(actionContext);
            }
        }

        //校验票据(数据库数据匹配)
        private bool ValidateTicket(string encryptToken)
        {
            bool flag = false;
            try
            {
                /*
                //获取数据库Token比对encryptToken
                Dec.Models.TicketAuth model = Dec.BLL.TicketAuth.GetTicketAuthByToken(encryptToken);
                model.Token == encryptToken
                if (flag) //存在
                {
                    //未超时
                    flag = (DateTime.Now <= model.ExpireDate) ? true : false;
                }
                */
                flag = false;  //实际使用过程需要比对数据库的Token是否存在且过期
            }
            catch (Exception ex) { }
            return flag;
        }

    }
}
using Magic.Tool;
using Newtonsoft.Json;
using System.Net.Http;
using System.Text;
using System.Web.Http;

namespace Magic.WebApi.Controllers
{
    public class OrderController : ApiController
    {
        [Route("api/order/detail")] //设置路由
        [HttpGet]
        [AuthFilter] //添加验证可在Action上也可以在ApiController上
        // GET: Order
        public HttpResponseMessage OrderDetail()
        {

            //int i = 0;
            //int t = i / 0; //尝试除以零 报错

            //定义
            ResultHelper obj = new ResultHelper();
            obj.data = "";
            obj.status = true;
            obj.msg = "获取数据成功";
            var resultObj = JsonConvert.SerializeObject(obj);
            HttpResponseMessage result = new HttpResponseMessage
            {
                Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json")
            };
            LogHelper.Log(resultObj);
            return result;
        }

        [Route("api/order/Index")] //设置路由
        [HttpGet]
        // GET: Order
        public HttpResponseMessage Index()
        {
            //定义
            ResultHelper obj = new ResultHelper();
            obj.data = "";
            obj.status = true;
            obj.msg = "获取订单数据成功";
            var resultObj = JsonConvert.SerializeObject(obj);
            HttpResponseMessage result = new HttpResponseMessage
            {
                Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json")
            };
            LogHelper.Log(resultObj);
            return result;
        }
    }
}

下面是跨域设置,主要是服务器端设置 Global文件里配置

        /// <summary>
        /// 配置Ajax跨域访问
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); // 可以设置为详细的地址
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS") // 加点逻辑
            {
                HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
                //需要Header传输的参数配置在这里 例如Token
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept,X-Requested-With,Token");
                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
                HttpContext.Current.Response.End();
            }
        }

@{
    ViewBag.Title = "Index";
}
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
    var token = "UIJHHBFFHHHGFRRRTA";
    //url因为是需要多次访问的,并且访问前缀都一样,所以需要单独保存,减少代码冗余量.
    var url = "http://xxxx.xxxx.xxxx.xxxx:8095/api/services/app/ProjectMonitor/";
    $.ajax({
        headers: {
            //Bearer是我的项目需要的,你可以按你的需求规范格式
            'Token': token
        },
        async: true,
        type: 'GET',
        dataType: "json",
        url: "http://localhost:66/api/order/index",
        data: {
            OrderID: 60000001,
            CustomerID: 80001
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            //错误访问所需执行的操作
            console.log(222);
        },
        success: function (data) {
            console.log(1111);
            console.log(data);
            //正确访问所需执行的操作
        }
    });

</script>
<h2>Index</h2>
       [Route("api/order/Index")] //设置路由
        [HttpGet]
        // GET: Order  api接口数据
        public HttpResponseMessage Index()
        {
            HttpContextBase context = (HttpContextBase)Request.Properties["MS_HttpContext"];//获取传统context
            HttpRequestBase request = context.Request;//定义传统request对象
            string Token = request.Headers["Token"];

            ResultHelper obj = new ResultHelper();
            obj.data = Token;
            obj.status = true;
            obj.msg = "获取订单数据成功";
            var resultObj = JsonConvert.SerializeObject(obj);
            HttpResponseMessage result = new HttpResponseMessage
            {
                Content = new StringContent(resultObj, Encoding.GetEncoding("UTF-8"), "application/json")
            };
            LogHelper.Log(resultObj);
            return result;
        }

猜你喜欢

转载自blog.csdn.net/smartsmile2012/article/details/82751674
今日推荐