zoukankan      html  css  js  c++  java
  • 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(12)-系统日志和异常的处理②

    上一讲我们做了日志与异常的结果显示列表,这一节我们讲要把他应用系统中来。

    首先我们在App.Common类库中创建一个通用类ResultHelper,这个类里面写了,获取一个GUID,获取当前时间,处理字符串等操作,虽然我们目前要用到的一个就是获取GUID但是以后我们可能还要用到别的,所以我都把他放进入了

    然后在App.Admin创建一个核心文件夹,Core,放入LogHandler这个类是主要是写入日志,避免在每次都要实例化这个类,我把他封装起来,大家一看就知道。

    然后修改Controller的Create方法,代码如下一一给出。

    using System;
    using System.Web;
    using System.Text.RegularExpressions;
    
    namespace App.Common
    {
        public class ResultHelper
        {
            /// <summary>
            /// 创建一个全球唯一的32位ID
            /// </summary>
            /// <returns>ID串</returns>
            public static string NewId
            {
                get
                {
                    string id = DateTime.Now.ToString("yyyyMMddHHmmssfffffff");
                    string guid = Guid.NewGuid().ToString().Replace("-", "");
                    id += guid.Substring(0, 10);
                    return id;
                }
            }
            public static string NewTimeId
            {
                get
                {
                    string id = DateTime.Now.ToString("yyyyMMddHHmmssfffffff");
                    return id;
                }
            }
            /// <summary>
            /// 截取字符串
            /// </summary>
            /// <param name="value">字符串</param>
            /// <param name="length">剩下长度</param>
            /// <returns>指定字符串并加...</returns>
            public static string SubValue(string value, int length)
            {
                if (value.Length > length)
                {
                    value = value.Substring(0, length); value = value + "..."; return NoHtml(value);
                }
                else { return NoHtml(value); }
            }
            //还原的时候
            public static string InputText(string inputString)
            {
    
                if ((inputString != null) && (inputString != String.Empty))
                {
                    inputString = inputString.Trim();
                    //if (inputString.Length > maxLength) 
                    //inputString = inputString.Substring(0, maxLength); 
                    inputString = inputString.Replace("<br>", "
    ");
                    inputString = inputString.Replace("&", "&amp");
                    inputString = inputString.Replace("'", "''");
                    inputString = inputString.Replace("<", "&lt");
                    inputString = inputString.Replace(">", "&gt");
                    inputString = inputString.Replace("chr(60)", "&lt");
                    inputString = inputString.Replace("chr(37)", "&gt");
                    inputString = inputString.Replace(""", "&quot");
                    inputString = inputString.Replace(";", ";");
    
                    return inputString;
                }
                else
                {
                    return "";
                }
    
            }
            //添加的时候
            public static string OutputText(string outputString)
            {
    
                if ((outputString != null) && (outputString != String.Empty))
                {
                    outputString = outputString.Trim();
                    outputString = outputString.Replace("&amp", "&");
                    outputString = outputString.Replace("''", "'");
                    outputString = outputString.Replace("&lt", "<");
                    outputString = outputString.Replace("&gt", ">");
                    outputString = outputString.Replace("&lt", "chr(60)");
                    outputString = outputString.Replace("&gt", "chr(37)");
                    outputString = outputString.Replace("&quot", """);
                    outputString = outputString.Replace(";", ";");
                    outputString = outputString.Replace("
    ", "<br>");
                    return outputString;
                }
                else
                {
                    return "";
                }
            }
            /// <summary>
            /// 去除HTML标记
            /// </summary>
            /// <param name="NoHTML">包括HTML的源码 </param>
            /// <returns>已经去除后的文字</returns>
            public static string NoHtml(string Htmlstring)
            {
                //删除脚本
                Htmlstring = Regex.Replace(Htmlstring, @"<script[^>]*?>.*?</script>", "", RegexOptions.IgnoreCase);
                //删除HTML
                Htmlstring = Regex.Replace(Htmlstring, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"([
    ])[s]+", "", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"-->", "", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"<!--.*", "", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"&(quot|#34);", """, RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"&(amp|#38);", "&", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"&(lt|#60);", "<", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"&(gt|#62);", ">", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"&(nbsp|#160);", " ", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"&(iexcl|#161);", "xa1", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"&(cent|#162);", "xa2", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"&(pound|#163);", "xa3", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"&(copy|#169);", "xa9", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"&#(d+);", "", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"&hellip;", "", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"&mdash;", "", RegexOptions.IgnoreCase);
                Htmlstring = Regex.Replace(Htmlstring, @"&ldquo;", "", RegexOptions.IgnoreCase);
                Htmlstring.Replace("<", "");
                Htmlstring = Regex.Replace(Htmlstring, @"&rdquo;", "", RegexOptions.IgnoreCase);
                Htmlstring.Replace(">", "");
                Htmlstring.Replace("
    ", "");
                Htmlstring = HttpContext.Current.Server.HtmlEncode(Htmlstring).Trim();
                return Htmlstring;
    
            }
            /// <summary>
            /// 格式化文本(防止SQL注入)
            /// </summary>
            /// <param name="str"></param>
            /// <returns></returns>
            public static string Formatstr(string html)
            {
                System.Text.RegularExpressions.Regex regex1 = new System.Text.RegularExpressions.Regex(@"<script[sS]+</script *>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex2 = new System.Text.RegularExpressions.Regex(@" href *= *[sS]*script *:", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex3 = new System.Text.RegularExpressions.Regex(@" on[sS]*=", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex4 = new System.Text.RegularExpressions.Regex(@"<iframe[sS]+</iframe *>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex5 = new System.Text.RegularExpressions.Regex(@"<frameset[sS]+</frameset *>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex10 = new System.Text.RegularExpressions.Regex(@"select", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex11 = new System.Text.RegularExpressions.Regex(@"update", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                System.Text.RegularExpressions.Regex regex12 = new System.Text.RegularExpressions.Regex(@"delete", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                html = regex1.Replace(html, ""); //过滤<script></script>标记
                html = regex2.Replace(html, ""); //过滤href=javascript: (<A>) 属性
                html = regex3.Replace(html, " _disibledevent="); //过滤其它控件的on...事件
                html = regex4.Replace(html, ""); //过滤iframe
                html = regex10.Replace(html, "s_elect");
                html = regex11.Replace(html, "u_pudate");
                html = regex12.Replace(html, "d_elete");
                html = html.Replace("'", "");
                html = html.Replace("&nbsp;", " ");
                return html;
            }
            /// <summary>
            /// 检查SQL语句合法性
            /// </summary>
            /// <param name="sql"></param>
            /// <returns></returns>
            public static bool ValidateSQL(string sql, ref string msg)
            {
                if (sql.ToLower().IndexOf("delete") > 0)
                {
                    msg = "查询参数中含有非法语句DELETE";
                    return false;
                }
                if (sql.ToLower().IndexOf("update") > 0)
                {
                    msg = "查询参数中含有非法语句UPDATE";
                    return false;
                }
    
                if (sql.ToLower().IndexOf("insert") > 0)
                {
                    msg = "查询参数中含有非法语句INSERT";
                    return false;
                }
                return true;
            }
            //获取当前时间
            public static DateTime NowTime
            {
                get 
                {
                    return DateTime.Now;
                }
            }
    
            /// <summary>
            /// 将日期转换成字符串
            /// </summary>
            /// <param name="dt">日期</param>
            /// <returns>字符串</returns>
            public static string DateTimeConvertString(DateTime? dt)
            {
                if (dt == null)
                {
                    return "";
                }
                else
                {
                    return Convert.ToDateTime(dt.ToString()).ToShortDateString();
                }
            }
            /// <summary>
            /// 将字符串转换成日期
            /// </summary>
            /// <param name="str">字符串</param>
            /// <returns>日期</returns>
            public static DateTime? StringConvertDatetime(string str)
            {
                if (str == null)
                {
                    return null ;
                }
                else
                {
                    try
                    {
                        return Convert.ToDateTime(str);
                    }
                    catch {
                        return null;
                    }
                }
            }
    
            public static string GetUserIP()
            {
                if (System.Web.HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null)
                    return System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].Split(new char[] { ',' })[0];
                else
                    return System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }
        }
    }
    
    ResultHelper
    ResultHelper
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using App.Common;
    using App.DAL;
    using App.IBLL;
    using App.Models;
    using Microsoft.Practices.Unity;
    
    namespace App.Admin
    {
        public static class LogHandler
        {
            [Dependency]
            public static ISysLogBLL logBLL { get; set; }
            /// <summary>
            /// 写入日志
            /// </summary>
            /// <param name="oper">操作人</param>
            /// <param name="mes">操作信息</param>
            /// <param name="result">结果</param>
            /// <param name="type">类型</param>
            /// <param name="module">操作模块</param>
            public static void WriteServiceLog(string oper, string mes, string result, string type, string module)
            {
               
                   
                    SysLog entity = new SysLog();
                    entity.Id = ResultHelper.NewId;
                    entity.Operator = oper;
                    entity.Message = mes;
                    entity.Result = result;
                    entity.Type = type;
                    entity.Module = module;
                    entity.CreateTime = ResultHelper.NowTime;
                    using (SysLogRepository logRepository = new SysLogRepository())
                    {
                        logRepository.Create(entity);
                    }
            
            }
        }
    }
    
    LogHandler
    LogHandler
    [HttpPost]
            public JsonResult Create(SysSampleModel model)
            {
    
    
                    if (m_BLL.Create(model))
                    {
                        LogHandler.WriteServiceLog("虚拟用户", "Id:" + model.Id + ",Name:" + model.Name, "成功", "创建", "样例程序");
                        return Json(1, JsonRequestBehavior.AllowGet);
                    }
                    else
                    {
                        LogHandler.WriteServiceLog("虚拟用户", "Id:" + model.Id + ",Name:" + model.Name, "失败", "创建", "样例程序");
                        return Json(0, JsonRequestBehavior.AllowGet);
                    }
         
            }
    
    SysSampleController
    SysSampleController

    同时App.Common要引用程序集System.Web

    运行添加一条记录,然后打开我们的日志模块,OK,日志记录完成了,有点简单。

    接下来是异常,上一讲说到,异常我们放在BLL中处理,然后我们把错误或者异常信息返回到Controller中被日志记录,当然异常他是在BLL层被记录的。

    我们需要一个异常的集合类,来记录BLL层和DAL层,有时候DAL也要处理异常,所以我们也要用到ref 引用传递,貌似ref我们很喜欢,呵呵

    见代码,在App.Common创建一个异常集合类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace App.Common
    {
        public class ValidationError
        {
            public ValidationError() { }
            public string ErrorMessage { get; set; }
           
        }
        public class ValidationErrors : List<ValidationError>
        {
            /// <summary>
            /// 添加错误
            /// </summary>
            /// <param name="errorMessage">信息描述</param>
            public void Add(string errorMessage)
            {
                base.Add(new ValidationError { ErrorMessage = errorMessage });
            }
            /// <summary>
            /// 获取错误集合
            /// </summary>
            public string Error
            {
                get {
                    string error = "";
                    this.All(a => {
                        error += a.ErrorMessage;
                        return true;
                    });
                    return error;
                } 
            }
        }
    }
    
    ValidationErrorHelper.cs

    我们也要创建一个封装好的异常写入,类似与Log的LogHandler封装但我们放在BLL中,因为我们以后的其他项目的BLL要引用,这一步要考虑到。
    在BLL中创建文件夹Core,写入以下类,BLL引用程序集System.Web里面用到了http的一些方法

    using System;
    using System.Web.Configuration;
    using App.Models;
    using System.IO;
    using System.Text;
    using App.Common;
    
    namespace App.BLL.Core
    {
    
            /// <summary>
            /// 写入一个异常错误
            /// </summary>
            /// <param name="ex">异常</param>
            public static class ExceptionHander
            {
                /// <summary>
                /// 加入异常日志
                /// </summary>
                /// <param name="ex">异常</param>
                public static void WriteException(Exception ex)
                {
                   
                        try
                        {
                            using (DBContainer db = new DBContainer())
                            {
                                SysException model = new SysException()
                                {
                                    Id = ResultHelper.NewId,
                                    HelpLink = ex.HelpLink,
                                    Message = ex.Message,
                                    Source = ex.Source,
                                    StackTrace = ex.StackTrace,
                                    TargetSite = ex.TargetSite.ToString(),
                                    Data =ex.Data.ToString(),
                                    CreateTime = ResultHelper.NowTime
                                    
                                };
                                db.SysException.AddObject(model);
                                db.SaveChanges();
                            }
                        }
                        catch (Exception ep)
                        {
                            try
                            {
                                //异常失败写入txt
                                string path = @"~/exceptionLog.txt";
                                string txtPath = System.Web.HttpContext.Current.Server.MapPath(path);//获取绝对路径
                                using (StreamWriter sw = new StreamWriter(txtPath, true, Encoding.Default))
                                {
                                    sw.WriteLine((ex.Message + "|" + ex.StackTrace + "|" + ep.Message + "|" + DateTime.Now.ToString()).ToString());
                                    sw.Dispose();
                                    sw.Close();
                                }
                                return;
                            }
                            catch { return; }
                        }
    
                    
    
                }
            }
    
        
    }
    
    ExceptionHander
    ExceptionHander

    此异常当处理也异常时候,将在网站根目录下写入一个txt文件。
    创建一个全局变量,在SysSampleController中定义

    ValidationErrors errors = new ValidationErrors();

    我们要用引用传递,所以要修改IBLL和BLL的Create方法,如下
    ISysSampleBLL  :  bool Create(ref ValidationErrors errors, SysSampleModel model);

    SysSampleBLL   :

    复制代码
     /// <summary>
            /// 创建一个实体
            /// </summary>
            /// <param name="errors">持久的错误信息</param>
            /// <param name="model">模型</param>
            /// <returns>是否成功</returns>
            /// <summary>
            /// 创建一个实体
            /// </summary>
            /// <param name="errors">持久的错误信息</param>
            /// <param name="model">模型</param>
            /// <returns>是否成功</returns>
            public bool Create(ref ValidationErrors errors, SysSampleModel model)
            {
                try
                {
                    SysSample entity = Rep.GetById(model.Id);
                    if (entity != null)
                    {
                        errors.Add("主键重复");
                        return false;
                    }
                    entity = new SysSample();
                    entity.Id = model.Id;
                    entity.Name = model.Name;
                    entity.Age = model.Age;
                    entity.Bir = model.Bir;
                    entity.Photo = model.Photo;
                    entity.Note = model.Note;
                    entity.CreateTime = model.CreateTime;
    
                    if (Rep.Create(entity) == 1)
                    {
                        return true;
                    }
                    else
                    {
                        errors.Add("插入失败");
                        return false;
                    }
                }
                catch (Exception ex)
                {
                    errors.Add(ex.Message);
                    ExceptionHander.WriteException(ex);
                    return false;
                }
            }
    复制代码

    修改Controller

    复制代码
     [HttpPost]
            public JsonResult Create(SysSampleModel model)
            {
                    if (m_BLL.Create(ref errors, model))
                    {
                        LogHandler.WriteServiceLog("虚拟用户", "Id:" + model.Id + ",Name:" + model.Name, "成功", "创建", "样例程序");
                        return Json(1, JsonRequestBehavior.AllowGet);
                    }
                    else
                    {
                        string ErrorCol = errors.Error;
                        LogHandler.WriteServiceLog("虚拟用户", "Id:" + model.Id + ",Name:" + model.Name + "," + ErrorCol, "失败", "创建", "样例程序");
                        return Json(0, JsonRequestBehavior.AllowGet);
                    }
         
            }
    复制代码

     注意:ExceptionHander.WriteException(ex);这里是写入异常信息

    OK,你现在可以创建一条新的记录和插入一个ID大于50个字符的记录,让他记录日志和异常了。

    显然我们的失败错误提示已经不符合国情了。我们返回的json格式是0和1我们要返回多个值了,比如1和成功创建,0和失败了啊,这样的2个值怎么办?

    controller能把datagrid传过来的东西用类来接受,那么反过来想,js也能把controller发出去的值分解,创建一个序列化的类

    在App.Common类库中创建JsonHandler帮助类,里面有2个重载,一个是返回3个值一个是2个值的。

    所以当我们要返回订单的数量和总价格的时候,我们将用到类似的手段

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace App.Common
    {
        public class JsonHandler
        {
    
            public static JsonMessage CreateMessage(int ptype,string pmessage,string pvalue)
            {
                JsonMessage json = new JsonMessage()
                {
                    type = ptype,
                    message = pmessage,
                    value = pvalue
                };
                return json;
            }
            public static JsonMessage CreateMessage(int ptype, string pmessage)
            {
                JsonMessage json = new JsonMessage()
                {
                    type = ptype,
                    message = pmessage,
                };
                return json;
            }
        }
    
        public class JsonMessage
        {
            public int type{get;set;}
            public string message{get;set;}
            public string value{get;set;}
        }
    }
    JsonHandler

    再次修改Controller的Create

    复制代码
      [HttpPost]
            public JsonResult Create(SysSampleModel model)
            {
                if (m_BLL.Create(ref errors, model))
                {
                    LogHandler.WriteServiceLog("虚拟用户", "Id:" + model.Id + ",Name:" + model.Name, "成功", "创建", "样例程序");
                    return Json(JsonHandler.CreateMessage(1, "插入成功"), JsonRequestBehavior.AllowGet);
                }
                else
                {
                    string ErrorCol = errors.Error;
                    LogHandler.WriteServiceLog("虚拟用户", "Id:" + model.Id + ",Name:" + model.Name + "," + ErrorCol, "失败", "创建", "样例程序");
                    return Json(JsonHandler.CreateMessage(0, "插入失败" + ErrorCol), JsonRequestBehavior.AllowGet);
                }
         
            }
    复制代码

    修改SysSample的Create的JS部分

    复制代码
    <script type="text/javascript">
        $(function () {
            $("#btnSave").click(function () {
                if ($("#CreateForm").valid()) {
                    $.ajax({
                        url: "/SysSample/Create",
                        type: "Post",
                        data: $("#CreateForm").serialize(),
                        dataType: "json",
                        success: function (data) {
                            if (data.type == 1) {
                                window.parent.frameReturnByMes(data.message);
                                window.parent.frameReturnByReload(true);
                                window.parent.frameReturnByClose()
                            }
                            else {
                                window.parent.frameReturnByMes(data.message);
                            }
                        }
                    });
                }
                return false;
            });
        });
        </script>
    复制代码

    由于时间关系,这一讲就先到这里吧!这一讲其实比较仓促。不懂的留言

    你需要继续做的就是在删除,编辑等操作也加入这些的。这点留给大家自己表现吧....

    下一讲是全局异常的捕获。

  • 相关阅读:
    Linux 命令笔记
    MySQL指令笔记
    悲观锁与乐观锁
    缓存在高并发场景下的常见问题
    死锁相关问题
    Java并发性和多线程
    Java同步和异步,阻塞和非阻塞
    内存溢出和内存泄漏
    JavaAndroid项目配置文件笔记
    Maven安装配置
  • 原文地址:https://www.cnblogs.com/zhangjunwei87/p/4680082.html
Copyright © 2011-2022 走看看