关于ASP.NET中过滤器、模子绑定的实例详解【C#.Net教程】,asp.net,mvc,模型绑定,asp.net,mvc,过滤器,mvc,模型绑定
作者:搜教程发布时间:2019-11-27分类:.Net教程浏览:33评论:0
一、过滤器(Filter)
ASP.NET MVC中的每一个要求,都邑分配给对应Controller(以下简称“掌握器”)下的特定Action(以下简称“要领”)处置惩罚,一般状况下直接在要领里写代码就能够了,然则假如想在要领实行之前或许以后处置惩罚一些逻辑,这里就须要用到过滤器。
经常运用的过滤器有三个:Authorize(受权过滤器),HandleError(非常过滤器),ActionFilter(自定义过滤器),对应的类分别是:AuthorizeAttribute、HandleErrorAttribute和ActionFilterAttribute,继续这些类并重写个中要领即可完成差别的功用。
1.Authorize受权过滤器
受权过滤器望文生义就是受权用的,受权过滤器在要领实行之前实行,用于限定要求能不能进入这个要领,新建一个要领:
public JsonResult AuthorizeFilterTest() { return Json(new ReturnModel_Common { msg = "hello world!" }); }
直接接见获得结果:
如今假定这个AuthorizeFilterTest要领是一个背景要领,用户必需得有一个有用的令牌(token)才接见,通例做法是在AuthorizeFilterTest要领里吸收并考证token,然则如许一旦要领多了,每一个要领里都写考证的代码明显不切实际,这个时刻就要用到受权过滤器:
public class TokenValidateAttribute : AuthorizeAttribute { /// <summary> /// 受权考证的逻辑处置惩罚。返回true则经由历程受权,false则相反 /// </summary> /// <param name="httpContext"></param> /// <returns></returns> protected override bool AuthorizeCore(HttpContextBase httpContext) { string token = httpContext.Request["token"]; if (string.IsNullOrEmpty(token)) { return false; } else { return true; } } }
新建了一个继续AuthorizeAttribute的类,并重写了个中的AuthorizeCore要领,这段伪代码完成的就是token有值即返回true,没有则返回false,标注到须要受权才够接见的要领上面:
[TokenValidate] public JsonResult AuthorizeFilterTest() { return Json(new ReturnModel_Common { msg = "hello world!" }) }
标注TokenValidate后,AuthorizeCore要领就在AuthorizeFilterTest之前实行,假如AuthorizeCore返回true,那末受权胜利实行AuthorizeFilterTest内里的代码,不然受权失利。不传token:
传token:
不传token受权失利时进入了MVC默许的未受权页面。这里做下革新:不论受权是胜利照样失利都保证返回值花样一致,轻易前端处置惩罚,这个时刻重写AuthorizeAttribute类里的HandleUnauthorizedRequest要领即可:
/// <summary> /// 受权失利处置惩罚 /// </summary> /// <param name="filterContext"></param> protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { base.HandleUnauthorizedRequest(filterContext); var json = new JsonResult(); json.Data = new ReturnModel_Common { success = false, code = ReturnCode_Interface.Token逾期或毛病, msg = "token expired or error" }; json.JsonRequestBehavior = JsonRequestBehavior.AllowGet; filterContext.Result = json; }
结果:
实战:受权过滤器最普遍的运用照样做权限治理体系,用户登录胜利后服务端输出一个加密的token,后续的要求都邑带上这个token,服务端在AuthorizeCore要领里解开token拿到用户ID,依据用户ID去数据库里查是不是有要求当前接口的权限,有就返回true,反之返回false。这类体式格局做受权,比拟登录胜利给Cookie和Session的优点就是一个接口PC端、App端配合运用。
2.HandleError非常过滤器
非常过滤器是处置惩罚代码非常的,在体系的代码抛错的时刻实行,MVC默许已完成了非常过滤器,而且注册到了App_Start目次下的FilterConfig.cs:
filters.Add(new HandleErrorAttribute());
这个见效于悉数体系,任何接口或许页面报错都邑实行MVC默许的非常处置惩罚,并返回一个默许的报错页面:Views/Shared/Error(递次发到服务器上报错时才够看到本页面,当地调试权限高,照样能够看到细致报错信息的)
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width" /> <title>毛病</title> </head> <body> <hgroup> <h1>毛病。</h1> <h2>处置惩罚你的要求时失足。</h2> </hgroup> </body> </html>
默许的非常过滤器明显没法满足运用需求,重写下非常过滤器,敷衍项目实战中的需求:
1)报错能够纪录毛病代码地点的掌握器和要领,以及报错时的要求参数和时候;
2)返回特定花样的JSON轻易前端处置惩罚。由于如今体系大部份是ajax要求,报错了返回MVC默许的报错页面,前端不优点置惩罚
新建一个类LogExceptionAttribute继续HandleErrorAttribute,并重写内部的OnException要领:
public override void OnException(ExceptionContext filterContext) { if (!filterContext.ExceptionHandled) { string controllerName = (string)filterContext.RouteData.Values["controller"]; string actionName = (string)filterContext.RouteData.Values["action"]; string param = Common.GetPostParas(); string ip = HttpContext.Current.Request.UserHostAddress; LogManager.GetLogger("LogExceptionAttribute").Error("Location:{0}/{1} Param:{2}UserIP:{3} Exception:{4}", controllerName, actionName, param, ip, filterContext.Exception.Message); filterContext.Result = new JsonResult { Data = new ReturnModel_Common { success = false, code = ReturnCode_Interface.服务端抛错, msg = filterContext.Exception.Message }, JsonRequestBehavior = JsonRequestBehavior.AllowGet }; } if (filterContext.Result is JsonResult) filterContext.ExceptionHandled = true;//返回结果是JsonResult,则设置非常已处置惩罚 else base.OnException(filterContext);//实行基类HandleErrorAttribute的逻辑,转向毛病页面 }
非常过滤器就不像受权过滤器一样标注在要领上面了,直接到App_Start目次下的FilterConfig.cs注册下,如许一切的接口都能够见效了:
filters.Add(new LogExceptionAttribute());
非常过滤器里运用了NLog作为日记纪录东西,Nuget装置敕令:
Install-Package NLog Install-Package NLog.Config
比拟Log4net,NLog设置简朴,仅几行代码即可,NLog.config:
<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <targets> <target xsi:type="File" name="f" fileName="${basedir}/log/${shortdate}.log" layout="${uppercase:${level}} ${longdate} ${message}" /> <target xsi:type="File" name="f2" fileName="D:\log\MVCExtension\${shortdate}.log" layout="${uppercase:${level}} ${longdate} ${message}" /> </targets> <rules> <logger name="*" minlevel="Debug" writeTo="f2" /> </rules> </nlog>
假如报错,日记就纪录在D盘的log目次下的MVCExtension目次下,一个项目一个日记目次,轻易治理。悉数设置完成,看下代码:
public JsonResult HandleErrorFilterTest() { int i = int.Parse("abc"); return Json(new ReturnModel_Data { data = i }); }
字符串强转成int范例,必定报错,页面相应:
同时日记也纪录下来了:
3.ActionFilter自定义过滤器
自定义过滤器就越发天真了,能够准确的注入到要求前、要求中和要求后。继续抽象类ActionFilterAttribute并重写内里的要领即可:
public class SystemLogAttribute : ActionFilterAttribute { public string Operate { get; set; } public override void OnActionExecuted(ActionExecutedContext filterContext) { filterContext.HttpContext.Response.Write("<br/>" + Operate + ":OnActionExecuted"); base.OnActionExecuted(filterContext); } public override void OnActionExecuting(ActionExecutingContext filterContext) { filterContext.HttpContext.Response.Write("<br/>" + Operate + ":OnActionExecuting"); base.OnActionExecuting(filterContext); } public override void OnResultExecuted(ResultExecutedContext filterContext) { filterContext.HttpContext.Response.Write("<br/>" + Operate + ":OnResultExecuted"); base.OnResultExecuted(filterContext); } public override void OnResultExecuting(ResultExecutingContext filterContext) { filterContext.HttpContext.Response.Write("<br/>" + Operate + ":OnResultExecuting"); base.OnResultExecuting(filterContext); } }
这个过滤器适合做体系操纵日记纪录功用:
[SystemLog(Operate = "增加用户")] public string CustomerFilterTest() { Response.Write("<br/>Action 实行中..."); return "<br/>Action 实行完毕"; }
看下结果:
四个要领实行递次:OnActionExecuting—>OnActionExecuted—>OnResultExecuting—>OnResultExecuted,非常准确的掌握了悉数要求历程。
实战中纪录日记历程是如许的:在OnActionExecuting要领里写一条操纵日记到数据库里,全局变量存下这条纪录的主键,到OnResultExecuted要领里申明要求完毕了,这个时刻天然晓得用户的这个操纵是不是胜利了,依据主键更新下这条操纵日记的是不是胜利字段。
二、模子绑定(ModelBinder)
先看一个一般的要领:
public ActionResult Index(Student student) { return View(); }
这个要领接收的参数是一个Student对象,前端通报过来的参数跟Student对象里的属性坚持一向,那末就自动被绑定到这个对象里了,不须要在要领里new Student这个对象并挨个绑定属性了,绑定的历程由MVC中的DefaultModelBinder完成的,DefaultModelBinder同时继续了IModelBinder接口,如今就应用IModelBinder接口和DefaultModelBinder来完成越发天真的模子绑定。
场景一、前端传过来了一个加密的字符串token,要领里须要用token里的某些字段,那就得在要领里吸收这个字符串、解密字符串、转换成对象,如许一个要领还好说,多了的话反复代码非常多,就算提取通用要领,照样要在要领里挪用这个通用要领,有无方法直接在参数里就封装好这个对象?
模子绑定的对象:
public class TokenModel { /// <summary> /// 主键 /// </summary> public int Id { get; set; } /// <summary> /// 姓名 /// </summary> public string Name { set; get; } /// <summary> /// 简介 /// </summary> public string Description { get; set; } }
新建一个TokenBinder继续IModelBinder接口并完成个中的BindModel要领:
public class TokenBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var token = controllerContext.HttpContext.Request["token"]; if (!string.IsNullOrEmpty(token)) { string[] array = token.Split(':'); if (array.Length == 3) { return new TokenModel() { Id = int.Parse(array[0]), Name = array[1], Description = array[2] }; } else { return new TokenModel() { Id = 0 }; } } else { return new TokenModel() { Id = 0 }; } } }
这个要领里吸收了一个token参数,并对token参数举行了剖析和封装。代码部份完成了须要到Application_Start要领里举行下注册:
ModelBinders.Binders.Add(typeof(TokenModel), new TokenBinder());
如今模仿下这个接口:
public JsonResult TokenBinderTest(TokenModel tokenModel) { var output = "Id:" + tokenModel.Id + ",Name:" + tokenModel.Name + ",Description:" + tokenModel.Description; return Json(new ReturnModel_Common { msg = output }); }
挪用下:
能够看出,“1:汪杰:oppoic.cnblogs.com”已被绑定到tokenModel这个对象内里了。然则假如稍庞杂的模子绑定IModelBinder就无计可施了。
场景二、去除对象某个属性的首位空格
public class Student { public int Id { get; set; } public string Name { get; set; } public string Class { get; set; } }
假如前端传来的Name属性有空格,怎样去除呢?应用DefaultModelBinder即可完成更天真的掌握
public class TrimModelBinder : DefaultModelBinder { protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) { var obj = base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder); if (obj is string && propertyDescriptor.Attributes[typeof(TrimAttribute)] != null)//推断是string范例且有[Trim]标记 { return (obj as string).Trim(); } return obj; } }
标注下须要花样化首位属性的实体:
[ModelBinder(typeof(TrimModelBinder))] public class Student { public int Id { get; set; } [Trim] public string Name { get; set; } public string Class { get; set; } }
好了,测试下:
public JsonResult TrimBinderTest(Student student) { if (string.IsNullOrEmpty(student.Name) || string.IsNullOrEmpty(student.Class)) { return Json(new ReturnModel_Common { msg = "未找到参数" }); } else { return Json(new ReturnModel_Common { msg = "Name:" + student.Name + ",长度:" + student.Name.Length + " Class:" + student.Class + ",长度:" + student.Class.Length }); } }
可见,标注了Trim属性的Name长度是去除空格的长度:7,而没有标注的Class属性的长度则是6。
【相干引荐】
1. ASP.NET免费视频教程
2. ASP.NET教程
3. 极客学院ASP,NET视频教程
以上就是关于ASP.NET中过滤器、模子绑定的实例详解的细致内容,更多请关注ki4网别的相干文章!
相关推荐
- 用 Composer 开源组件构建自己的 PHP 框架_php教程,php,框架,mvc
- 实例引见asp.net项目开辟中罗列的运用【C#.Net教程】,asp.net,枚举
- 分享一个asp.net完成多个文件同时下载的要领【C#.Net教程】,asp.net,多文件下载
- asp.net core实例教程之非常处置惩罚与静态文件教程【C#.Net教程】,asp.net ,core,异常处理,静态文件
- Asp.Net MVC进修总结之过滤器详解(图文详解)【C#.Net教程】,asp.net,mvc,过滤器
- asp.net core mvc权限掌握 在视图中掌握操纵权限的代码示例细致引见【C#.Net教程】,asp.net,core,mvc
- asp.net怎样运用js文件【C#.Net教程】,asp.net
- asp.net是什么【C#.Net教程】,asp.net,asp.net是什么
- asp.net与php哪一个好?【php问题】,asp.net,php
- asp.net mvc中完成Forms身份验证身份验证流程的实例【C#.Net教程】,asp.net,Forms,验证
你 发表评论:
欢迎- .Net教程排行
-
- 1案例分享c++ map的运用和 查找机能测试【C#.Net教程】,性能,map,c++
- 2细致引见C# string花样的日期时候字符串转为DateTime范例的要领【C#.Net教程】,C#,string,DateTime
- 3c#怎样运用?c#的基础语法【C#.Net教程】,c#,关键字
- 4详解ASP.NET中衔接数据库设置要领【C#.Net教程】,ASP.NET,数据库,配置
- 5C# DataSet机能最好实践【C#.Net教程】,C#,DataSet
- 6.net和c#有什么区别【C#.Net教程】,.net,c#
- 7C#_挪用封装的一个类完成导出Excel表格的功用【C#.Net教程】,C# Excel表格
- 8asp .net 面试题及答案分享【C#.Net教程】,.net,自己,整理,问题,面试
- 9让WebAPI 返回JSON花样的数据实例教程【C#.Net教程】,javascript,WebAPI,JSON,api,web,搭建,返回
- 最新文章
- 广而告之