ASP.NET MVC
绝大多数的公司已经用上了ASP.NET MVC,博主手里也做了不少个MVC的项目,在这里分享一下我在项目中是如何使用MVC的
打造通用的异常处理
项目上线运行,并不是所有的时候都正常运行的,偶尔也会崩溃报错。发生各种各样的例外,这并不是可怕因为这是每一个项目都无法去避免的。而我们能做的就是针对异常进行收集处理分析,以便在第一时间发现问题去修改bug。
如果每一个action都用try{}…catch{}..包围的话,那自然并不是什么优秀的处理。MVC给我们提供了好用的filter,我们可以自定义一个处理异常的filter。
这时需要思考,filter应该放在哪里?是在web项目中吗?显然公司并不只有一个项目,就算是后台也会是一个单独的项目。难道做新项目的时候都要把filter拷贝过去?这显然是不合理的。我的做法是放在基础设施里。
上图中MvcExceptionFilterAttribute就是异常处理过滤器了,而FilterConfig则是把过滤器添加到filter集合中,这样带来的效果就是,如果有项目需要进行异常处理,只需要引用这个项目并且在global里使用filterconfig的RegisterGlobalFilters方法来注册过滤器就可以了
/// <summary> /// Mvc异常过滤器 /// </summary> public class MvcExceptionFilterAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { try { filterContext.Exception.ToExceptionless().Submit(); } finally { //设置为true阻止golbal里面的错误执行 filterContext.ExceptionHandled = true; filterContext.Result = new JsonResult() { Data = ResponseManager.GetOutputResponse(OutputStatus.Error), JsonRequestBehavior = JsonRequestBehavior.AllowGet }; } } }
public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { //全局异常过滤 filters.Add(new MvcExceptionFilterAttribute()); filters.Add(new MvcActionProcessFilterAttribue()); } }
//初始化filter FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
打造通用的模型验证
mvc为我们提供了模型验证,我们只需要使用ModelState.IsValid就可以进行参数合法性验证,当然这需要我们使用Data Annotations或Fluent API。这使得在我们不需要在每个用到这个实体的方法里做一大堆的参数验证,但是仍然要在Action中判断ModelState.IsValid。我需要的是只要进入了这个action,那么参数都是合法的。这是AOP的思想,使开发者更专注业务,而不是一堆繁琐的验证。
打造一个通用的模型验证显的很必要,首先创建一个ModelValidAttribute类继承ActionFilterAttribute。重写OnActionExecuting方法,在方法里进行参数验证。在需要进行验证的action贴上ModelValid注解即可
/// <summary> /// Model参数验证拦截器 /// </summary> public class ModelValidAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { var con = filterContext.Controller as Controller; if (!con.ModelState.IsValid) { string errorMessage = "服务器繁忙,请稍后再试"; foreach (var value in con.ModelState.Values) { if (!value.Errors.AsEnumerable().Any()) continue; foreach (var error in value.Errors) { errorMessage = error.ErrorMessage; break; } break; } filterContext.Result = new JsonResult() { Data = ResponseManager.GetOutputResponse(OutputStatus.NoParameter, errorMessage), JsonRequestBehavior = JsonRequestBehavior.AllowGet }; } } }
[ModelValid] public async Task<ContentResult> Login(Login input) { return JsonData(await LoginService.Login(input)); }