zoukankan      html  css  js  c++  java
  • WebAPI异常捕捉处理,结合log4net日志(webapi2框架)

    一:异常捕捉处理

      首先,在我们需要区分controller的类型。是全部基层controller,还是Apicontroller。(当然一般API框架,用的都是Apicontroller)。两者异常处理是不同的。

     1.apicontroller  webapi框架错误处理:

    首先在App_Start里添加一个新类,继承于ExceptionFilterAttribute类

    复制代码
    public class WebApiExceptionFilterAttribute : ExceptionFilterAttribute
    {
          //重写基类的异常处理方法
            #region
            public override void OnException(HttpActionExecutedContext actionExecutedContext)
            {
                
    
                //2.返回调用方具体的异常信息
                if (actionExecutedContext.Exception is NotImplementedException)
                {
                    var oResponse = new HttpResponseMessage(HttpStatusCode.NotImplemented);
                    //oResponse.Content = new StringContent("方法不被支持");
                    oResponse.Content = new StringContent(actionExecutedContext.Exception.Message);
                    oResponse.ReasonPhrase = "This Func is Not Supported";
                    actionExecutedContext.Response = oResponse;
                }
                else if (actionExecutedContext.Exception is TimeoutException)
                {
                    actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.RequestTimeout);
                }
                //.....这里可以根据项目需要返回到客户端特定的状态码。如果找不到相应的异常,统一返回服务端错误500
                else
                {
                    // actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.InternalServerError);
    
    
                    //注释掉错误信息的展示,显示统一的错误
                    var Message = JsonHelper.GetJsonString(new { Errorcode = HttpStatusCode.InternalServerError, message = actionExecutedContext.Exception.Message});
                    //写日志
                    ILog log = LogManager.GetLogger(typeof(GoodsController));
                    log.Error(Message, new Exception("Error异常"));
    
                    // 自定义message的错误信息
                    //var Message =JsonHelper.GetJsonString(new {Errorcode = HttpStatusCode.InternalServerError, message = "接口调用失败,请检查传入参数是否正确"});
    
    
                    var oResponse = new HttpResponseMessage(HttpStatusCode.InternalServerError)
                    {
                      //Content = new StringContent(actionExecutedContext.Exception.Message),
                      Content = new StringContent(Message),
                      ReasonPhrase = "Error"
                    };
                    actionExecutedContext.Response = oResponse;
                }
    
                base.OnException(actionExecutedContext);
            }
            #endregion
    
    }
    复制代码

    看个人需求是全局捕捉错误,还是区域捕捉。

    全局:Global里加上这句。GlobalConfiguration.Configuration.Filters.Add(new WebApiExceptionFilterAttribute());

     区域: 这ApiController或是方法名称前加一个特性就OK了。

     2.继承controller的 还是MVC那一套(在Global中添加 Application_Error方法)

    复制代码
    protected void Application_Error(object sender, EventArgs e)
            {
                // 在出现未处理的错误时运行的代码
                HttpContext ctx = HttpContext.Current;
                Exception exception = ctx.Server.GetLastError();
                Exception exception_s = Server.GetLastError();
                HttpException ex = exception_s as HttpException;
                if (exception != null)
                {
                    string m = exception.Message;
                    string errorInfo = "URL:<strong>" + ctx.Request.RawUrl.ToString() + "<strong><br/>Source:<strong>" + exception.Source
                                       + "<strong><br/>Message:<strong>" + exception.Message + "<>";
                    if (!m.Contains("不存在"))
                    {
                        if (exception.InnerException != null)
                            errorInfo += "<br/>错误信息为:<strong>" + exception.InnerException.Message + "<>";
                    }
                    if (exception is HttpException)
                    {
                        HttpException ex2 = exception as HttpException;
                        int httpCode = ex2.GetHttpCode();
                        errorInfo += "<br />Code:<strong>" + httpCode.ToString() + "<>";
                    }
    
                    //写日志
                    ILog log = LogManager.GetLogger(typeof(GoodsController)); 
                    log.Error(errorInfo, new Exception("Error异常")); ctx.Items.Add("LastError", errorInfo); ctx.Server.ClearError(); 
    }

    try { //写逻辑 ctx.Response.Redirect("/Home/Index"); } catch { }
    }
    复制代码

    二:log4net日志管理。配合WebApi框架,个人感觉十分方便

    打开NuGet,添加log4net。成功之后,可以直接处理

    使用方法:

    复制代码
     [HttpGet,Route("LogTest")]
            public IHttpActionResult LogTest()
            {
                ILog log = LogManager.GetLogger(typeof(GoodsController)); // 下面是日志处理
                log.Debug("测试debug", new Exception("debug异常"));
                log.Info("测试Info", new Exception("Info异常"));
                log.Warn("测试Warn", new Exception("Warn异常"));
    
                log.Error("测试Error", new Exception("Error异常"));
                log.Fatal("测试Fatal", new Exception("Fatal异常"));
                return Json(new {result = "Complent"});
            }
    复制代码

    log4net需要配置文件,才能输出。添加Log4net.config文件。然后在程序集AssemblyInfo.cs中,添加 [assembly: XmlConfigurator(Watch = true, ConfigFile = "Log4Net.config")]

    复制代码
    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    
    
      <log4net>
        <!--记录所有的完整日志-->
        <appender name="AllLogFileAppender" type="log4net.Appender.RollingFileAppender">
          <!--或者是文件名或是文件夹(没有后缀)Gets or sets the path to the file that logging will be written to.,-->
          <file value="log/all/log_" />
          <!--是否总是写在一个文件里Gets or sets a value indicating whether to always log to the same file.-->
          <staticLogFileName value="false" />
          <!--Gets or sets a flag that indicates whether the file should be appended to or overwritten.-->
          <appendToFile value="true" />
          <!--可设置为Size、Date,即大小/日期超出一定范围后就新建一个日志文件-->
          <rollingStyle value="Date" />
          <!--一天最多保存多少Gets or sets the maximum number of backup files that are kept before the oldest is erased.-->
          <maxSizeRollBackups value="10" />
          <!--每个文件最大大小,单位可是MB,KBGets or sets the maximum size that the output file is allowed to reach before being rolled over to backup files.-->
          <maximumFileSize value="5MB" />
          <!--设置用来生产文件的日期格式Gets or sets the date pattern to be used for generating file names when rolling over on date.-->
          <datePattern value="yyyy-MM-dd'.log'"/>
          <!--日志输入的通用格式(日志的内容格式)-->
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
          </layout>
          <filter type="log4net.Filter.LevelRangeFilter,log4net">
            <!--级别由低往高依次是
            ALL
            DEBUG
            INFO
            WARN
            ERROR
            FATAL
            None-->
            <levelMin value="DEBUG" />
            <levelMax value="Warn" />
          </filter>
        </appender>
    
        <!--记录错误日志,这些错误往往是一个程序bug或是要注意的-->
        <appender name="ErrorLogFileAppender" type="log4net.Appender.RollingFileAppender">
          <!--或者是文件名或是文件夹(没有后缀)Gets or sets the path to the file that logging will be written to.,-->
          <file value="log/error/error_" />
          <!--是否总是写在一个文件里Gets or sets a value indicating whether to always log to the same file.-->
          <staticLogFileName value="false" />
          <!--Gets or sets a flag that indicates whether the file should be appended to or overwritten.-->
          <appendToFile value="true" />
          <!--可设置为Size、Date,即大小/日期超出一定范围后就新建一个日志文件-->
          <rollingStyle value="Date" />
          <!--一天最多保存多少Gets or sets the maximum number of backup files that are kept before the oldest is erased.-->
          <maxSizeRollBackups value="10" />
          <!--每个文件最大大小,单位可是MB,KBGets or sets the maximum size that the output file is allowed to reach before being rolled over to backup files.-->
          <maximumFileSize value="5MB" />
          <!--设置用来生产文件的日期格式Gets or sets the date pattern to be used for generating file names when rolling over on date.-->
          <datePattern value="yyyy-MM-dd'.log'"/>
          <!--日志输入的通用格式(日志的内容格式)-->
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
          </layout>
          <filter type="log4net.Filter.LevelRangeFilter,log4net">
            <levelMin value="ERROR" />
            <levelMax value="FATAL" />
          </filter>
        </appender>
        <!--Set root logger level to DEBUG and its only appender to A1-->
        <root>
          <!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF-->
          <level value="ALL" />
          <appender-ref ref="AllLogFileAppender" />
          <appender-ref ref="ErrorLogFileAppender" />
        </root>
      </log4net>
      <system.web>
          <compilation debug="true" targetFramework="4.5.2" />
          <httpRuntime targetFramework="4.5.2" />
        </system.web>
    
    </configuration>
    复制代码

     上面只是写了一个,测试方法而已。WebAPI实际使用本文全局错误处理 + log4net,日志模块简直起飞。遇到问题,系统BUG之类的也不用慌,去日志里找就行了,全都记录了。

    原文链接:https://www.cnblogs.com/cr-cool/p/12073052.html

    世界再大也有尽头!
  • 相关阅读:
    VS 2008潜在强大的功能:提取EXE文件中的ICO等资源
    园友们注意:淘宝网上QQ会员 4钻 3元 等都为骗子行为
    Comet Async Process Request Handler
    WCF(Sender) to MSMQ to WCF(Receiver)
    ASP.NET Web Form GridView DetailsView Query Edit
    WCF NetTcp AsyncQueue Service
    Xml CDATA 序列化
    Sync Invoke Remoting Async Invoke
    .Net 4.0 Remoting ConcurrentQueue
    Socket Async Receive Data to LinkedList Buffer (telnet proxy server)
  • 原文地址:https://www.cnblogs.com/shijiehaiyang/p/14901552.html
Copyright © 2011-2022 走看看