jQuery Validate http://www.runoob.com/jquery/jquery-plugin-validate.html
Mvc校验及数据批注解耦方法 创建模型类
1 2 3 4 5 6 7 8 public class UserInfo { [StringLength(10,ErrorMessage = "*10个字符以内" ) ] public string Name { get ; set ; } [Range(0,130,ErrorMessage = "*0到130岁之间" ) ] public int Age { get ; set ; } }
通过模型类的数据批注,mvc中html帮助器方法会创建带校验的html属性
1 2 3 4 5 6 7 <div class ="form-group" > @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" }) <div class ="col-md-10" > @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Name, "" , new { @class = "text-danger" }) </div> </div>
Html.ValidationMessageFor
中显示errormessage
,生成对应的html标签:
1 <input class ="form-control text-box single-line" data-val ="true" data-val-number ="字段 Age 必须是一个数字。" data-val-range ="*0到130岁之间" data-val-range-max ="130" data-val-range-min ="0" data-val-required ="Age 字段是必需的。" id ="Age" name ="Age" type ="number" value ="" />
是通过反射元数据实现对特性的校验,js中使用的jquery validate实现的校验,服务器端校验可以通过ModelState.IsValid
进行校验
有关从数据库中取出的数据,进行的数据批注会在每次模型改变时模板类的重新生成时消失,可以通过往同一名字的类中添加元数据进行解耦,最后结果是一样的
模型改为parital
1 2 3 4 5 6 7 8 9 namespace _61 .Models { public partial class UserInfo { public string Name { get ; set ; } public int Age { get ; set ; } } }
通过MetadataType特性共享UserInfoValidate的元数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 namespace _61 .Models { [MetadataType(typeof(UserInfoValidate))] public partial class UserInfo { } public class UserInfoValidate { [StringLength(10 , ErrorMessage = "*10个字符以内" )] public string Name { get ; set ; } [Range(0 , 130 , ErrorMessage = "*0到130岁之间" )] public int Age { get ; set ; } } }
补充:程序集包含:IL,元数据,Resource,程序集清单
元数据: 元数据以非特定语言的方式描述在代码中定义的每一类型和成员。元数据存储以下信息:
程序集的说明。
标识(名称、版本、区域性、公钥)。
导出的类型。
该程序集所依赖的其他程序集。
运行所需的安全权限。
类型的说明。
名称、可见性、基类和实现的接口。
成员(方法、字段、属性、事件、嵌套的类型)。
属性。
Mvc Ajax 控制器
1 2 3 4 5 6 7 8 9 10 public ActionResult Index ( ) { return View(); } public string GetTime (string message ) { Thread.Sleep(1000 ); return $"{DateTime.Now.ToString()} --{message} " ; }
view
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 @section scripts { <script src ="~/Scripts/jquery.unobtrusive-ajax.min.js" > </script > <script > $(function ( ) { $("#loading" ).css("display" , "none" ); }); function SuccessGetTime () { alert("success" ); } </script > } @using (Ajax.BeginForm("GetTime",new AjaxOptions() { Confirm = "确认提交?", HttpMethod = "Post", LoadingElementId = "loading", OnSuccess = "SuccessGetTime", UpdateTargetId = "result" })) { <input type ="text" name ="message" /> <input type ="submit" value ="submit" /> } <div id ="loading" > 正在加载</div > <div id ="result" > </div >
添加引用包<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
new AjaxOptions()对象
过滤器 https://luox78.github.io/2018/02/28/filters/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class MyActionFilterAttribute : ActionFilterAttribute { public string Name { get ; set ; } public override void OnActionExecuting (ActionExecutingContext filterContext ) { base .OnActionExecuting(filterContext); filterContext.HttpContext.Response.Write(Name + " <h1>before action</h1>" ); } public override void OnActionExecuted (ActionExecutedContext filterContext ) { base .OnActionExecuted(filterContext); filterContext.HttpContext.Response.Write(Name + " <h1>after action</h1>" ); } public override void OnResultExecuting (ResultExecutingContext filterContext ) { base .OnResultExecuting(filterContext); filterContext.HttpContext.Response.Write(Name + " <h1>before Result</h1>" ); } public override void OnResultExecuted (ResultExecutedContext filterContext ) { base .OnResultExecuted(filterContext); filterContext.HttpContext.Response.Write(Name + " <h1>after Result</h1>" ); } }
Name用于区分是谁的过滤器
1 2 3 4 5 [MyActionFilter(Name = "Action" )] public ActionResult Index() { return View () ; }
页面顺序:Action:before action → after action → before Result → after Result
添加全局的过滤器
1 2 3 4 5 6 7 8 9 10 public class FilterConfig { public static void RegisterGlobalFilters (GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); filters.Add(new MyActionFilterAttribute()); } }
添加整个控制器过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [MyActionFilter(Name = "Controller" ) ] public class AjaxController : Controller { [MyActionFilter(Name = "Action" ) ] public ActionResult Index ( ) { return View(); } public string GetTime (string message ) { Thread.Sleep(1000 ); return $"{DateTime.Now.ToString(CultureInfo.InvariantCulture)} --{message} " ; } }
此时生成仍然是action的过滤器,因为过滤器会默认最近原则,可以使用AttributeUsage特性改变特性属性
1 2 [AttributeUsage(AttributeTargets.All, AllowMultiple = true )] public class MyActionFilterAttribute : ActionFilterAttribute{。。。}
此时html
全局 before action→ Controller before action→ Action before action → Action after action→ Controller after action→ 全局 after action→ 全局 before Result→ Controller before Result→ Action before Result→ Action after Result→ Controller after Result→ 全局 after Result
Areas 在大型的ASP.NET mvc 5项目中一般都有许多个功能模块,这些功能模块可以用Area(中文翻译为区域)把它们分离开来,比如:Admin,Customer,Bill。ASP.NET MVC项目中把各个功能分为不同Area的之后每一个Area都有独立的Controller,View文件结构。这样可以把这些功能分给不同的开发者同时开发而彼此之间不会冲突,这样的文件结构各司其职,直观明了,易于维护和管理。下面我们看看怎么在ASP.NET MVC5中创建一个Area和Area直接之间链接的处理。
生成的AreaRegistration中写了自己的路由规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 namespace _61 .Areas .luox78 { public class luox78AreaRegistration : AreaRegistration { public override string AreaName { get { return "luox78" ; } } public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "luox78_default" , "luox78/{controller}/{action}/{id}" , new { action = "Index" , id = UrlParameter.Optional } ); } } }
Global.asax.cs中注册了区域路由
1 2 3 4 5 public class MvcApplication : System.Web.HttpApplication { protected void Application_Start () { AreaRegistration.RegisterAllAreas();
在Area区域的视图之间Action的链接跳转的处理 1、同一个Area之间跳转
在Area区域的视图中生成指向同一个Area的Action链接时,你不需要做任何处理,当你调用Html.ActionLink时MVC框架自动去找当前Area的相应路由来生成Action的链接。如下:
1 @Html .ActionLink ("Click me", " About")
2、不同Area之间跳转
2、不同Area之间跳转 1 @Html .ActionLink("Click me to go to another area" , "Index" , new { area = "Support" })
3、跳转到Area外部,使用RouteLink即可
1 @Html.RouteLink("click to ajax index" , "default" , new { area = "" , controller = "Home" , action = "About" })