博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MVC查询数据接收及校验
阅读量:6692 次
发布时间:2019-06-25

本文共 20059 字,大约阅读时间需要 66 分钟。

本来想写一篇aspx的TreeView控件绑值的文章的,在写案例的时候,写了一半,发现有些地方还得考虑以下,就留待下次了。

这一篇的话,是最近在开发一个项目的时候,有大量的页面和数据表,需要花式查询,

后台接收前台传递过来的数据的时候,被虐的欲仙欲死,大量的校验和重复代码,

后来找到了一种非常不错的方法,分享出来,下面是正文。。。。。

 

使用过MVC的人都知道,它有一个非常方便的功能,就是自动绑值,先来一个最简单的:

1         public ActionResult Index(string userName, int type) {2             /*3              代码块4              */5             return View();6         }

当从前台传递过来的数据中,有两个参数名字为userName或type时,MVC会自动帮我们将参数类型转好,值给好。

我们要做的无非是直接使用罢了,但是,当要传递的值非常多的时候,无论是写还是看,都会非常吃力,比如这样:

1         public ActionResult Index01(string userName, int type, string code, int height, string sex, DateTime startTime, DateTime endTime) {2             /*3              代码块4              */5             return View();6         }

其实,七个查询参数并不多,当参数数量达到十个,二十个时,相信我,你会炸的,

一般这个时候,我们可用选择使用对象,就像这样:

1         public ActionResult Index01(User user) { 2             /* 3              代码块 4              */ 5             return View(); 6         } 7  8     ///  9     /// 用户类10     /// 11     public class User {12 13         /// 14         /// 用户姓名15         /// 16         public string userName;17 18         /// 19         /// 用户类型20         /// 21         public int type;22 23         /// 24         /// 身份证号25         /// 26         public string code;27 28         /// 29         /// 用户身高30         /// 31         public int height;32 33         /// 34         /// 用户性别35         /// 36         public string sex;37 38         #region 注册时间范围39 40         public DateTime startTime;41         public DateTime endTime;42 43         #endregion44 45     }

这样写是不是看起来舒服了很多?MVC同样能够帮你将数据依次绑好,同时,代码的复用率也会提高很多,

现在解决了数据接收的问题,接下来的,就是数据的校验了。

==========分隔符==========

拿到参数后,我们是不能立刻去使用的,需要对参数进行一次校验,校验的目的,就是防止有人恶意传递错误数据给后台,

若不进行数据校验的话,很容易导致项目崩溃,或者数据丢失等等一系列问题,简单的说一些校验类型吧,

string 变量,主要校验是否包含sql注入字符,然后判断是否为null,还要去掉多余的空格

int 变量,主要检验是否在某一个范围内,以及默认值是0还是-1,或者是其它的一些数字

DateTime 变量,一般都是两个一起使用,一个开始一个结束,这个时候我们就要校验,开始时间是否小于或等于结束时间,以及结束时间是否小于或等于当前时间,

还有一点值得注意的是,若开始时间和结束时间精确到天时,若是同一天,在数据库是无法查出数据的,所以必须精确到秒

 

我们按这个思路去添加校验:

public ActionResult Index01(User user) {            // 字符串校验            // 判断是否为空为null            if (string.IsNullOrEmpty(user.userName))                user.userName = user.userName.Trim();// 去掉多余空格            // SQL注入校验            if (CheckSQL(user.userName))                user.userName = "";// 替换掉带有SQL注入的字符            // 数字校验            if (user.type < 0 || 20 < user.type)                user.type = 0;// 当范围不在[0,20]时,给默认值0            // 时间校验            /*              没有六七十行搞不定,就不写了,,,             */            return View();        }

看起来还是不错的,但如果考虑到,每个数据的范围不一样,校验也是各不相同,而且,一个数据校验最少就得写两行代码,

当参数多了的时候,光校验代码都得写上一两百行,可以想想,如果有一百个类似的页面,呵呵。。。

不仅仅是看的难受,维护也是相当困难的,

所以我就想,能不能前台向后台请求的数据,都用一个类来接收,所有的校验都写在这个类里面,

类的每个参数,在输出的时候,都进行校验,这样可用极大的省略,接收数据之后在视图中的校验,而是将校验放在一起,

同时,相同校验方法的的参数,可用限制参数名为同一个,代码的复用率也会得到提升,对于维护和修改也能轻松进行,,,

 

说干就干,当时写出来的类,经过这么久的修改和添加,已经可以拿出来溜溜了,先上使用代码吧:

1         public ActionResult Index01(ReqData data) { 2  3             string sqlstr = string.Format(" select * from dt_user where userName='{0}' ", data.UserName); 4  5             /* 6              执行sql语句,以及其他操作,,, 7              */ 8  9             return View();10         }

有没有瞬间感觉画风不对,说好的校验哪去了?怎么能直接使用??

其实,所有的校验都在ReqData这个类里面,可以在它里面添加自己需要的参数,以及对应的校验方法,这样,使用的时候就会非常简单了

我主要想要分享的是一种封装的思想和技巧,可能ReqData这个类还是很简陋,但还是希望能对大家有所帮助,好像有点长,贴上代码先:

 

1 using System;  2   3 namespace Demo.Model {  4   5     ///   6     /// 用于接收前台传过来的数据  7     ///   8     public struct ReqData {  9  10         #region 分页数据 11  12         ///  13         /// 数据总行数 14         ///  15         public int PageCount { get; set; } 16  17         ///  18         /// 当前页码 19         ///  20         public int PageIndex { 21             get { 22                 if (pageIndex == 0) 23                     pageIndex = 1; 24                 return pageIndex; 25             } 26             set { 27                 pageIndex = value; 28             } 29         } 30         private int pageIndex; 31  32         ///  33         /// 每页行数 34         ///  35         public int PageSize { 36             get { 37                 if (pageSize == 0) 38                     pageSize = 10; 39                 return pageSize; 40             } 41             set { 42                 pageSize = value; 43             } 44         } 45         private int pageSize; 46  47         ///  48         /// 页面跳转链接,带参数 49         /// 用于分页跳转 50         ///  51         public string PageUrl { get; set; } 52  53         ///  54         /// 页面跳转链接,不带参数 55         /// 用于删除时跳转 56         ///  57         public string GetPageUrl { 58             get { 59                 // 判断是否为空 60                 if (PageUrl == null) 61                     return ""; 62  63                 // 检测是否有参数 64                 int index = PageUrl.LastIndexOf("?"); 65                 // 去掉参数 66                 if (index > 0) 67                     return PageUrl.Substring(0, index); 68                 return PageUrl; 69             } 70         } 71  72         #endregion 73  74         #region 页面参数 75  76         ///  77         /// 视图样式,{ txt:列表视图,img:图片视图 } 78         ///  79         public string Show { 80             get { 81                 CheckStr(ref show); 82  83                 if (string.IsNullOrEmpty(show)) 84                     show = "txt"; 85                 if (show != "txt" && show != "img") 86                     show = "txt"; 87                 return show; 88             } 89             set { show = value; } 90         } 91         private string show; 92  93         ///  94         /// 导航栏标题 95         ///  96         public string Title { 97             get { return CheckStr(ref title); } 98             set { title = value; } 99         }100         private string title;101 102         #endregion103 104         #region 查询参数105 106         /// 107         /// 用户编号108         /// 109         public int? ID {110             get { return id; }111             set { id = value; }112         }113         private int? id;114 115         /// 116         /// 用户名117         ///   118         public string UserName {119             get { return CheckStr(ref userName); }120             set { userName = value; }121         }122         private string userName;123 124         /// 125         /// 用户等级,范围:[0,3]126         /// 127         public int? Leavel {128             get { return GetNumInMinToMax(ref leavel, 0, 3); }129             set { leavel = value; }130         }131         private int? leavel;132         133         #region 时间参数134 135         #region 时间接收136         137         private DateTime? start_Time;138         /// 139         /// 开始时间,时分秒为 0:0:0,并且不能大于End_Time140         /// 141         public DateTime? Start_Time {142             get {143                 // 允许开始时间为空144                 if (start_Time == null)145                     return start_Time;146 147                 // 若开始时间大于当前时间148                 if (start_Time.Value > DateTime.Now)149                     // 开始时间为当前时间150                     start_Time = DateTime.Now;151 152                 // 当结束时间不为空153                 if (end_Time != null)154                     // 当开始时间大于结束时间时155                     if (start_Time > End_Time)156                         // 取结束时间当天的凌晨157                         start_Time = new DateTime(End_Time.Value.Year, End_Time.Value.Month, End_Time.Value.Day, 0, 0, 0);158 159                 return start_Time;160             }161             set { start_Time = value; }162         }163 164         private DateTime? end_Time;165         /// 166         /// 结束时间,时分秒为 23:59:59,并且不能大于当前时间167         /// 168         public DateTime? End_Time {169             get {170                 // 允许结束时间为空171                 if (end_Time == null)172                     return end_Time;173 174                 // 若结束时间大于当前时间175                 if (end_Time.Value >= DateTime.Now)176                     // 结束时间为当前时间177                     end_Time = DateTime.Now;178                 else {179                     // 获取结束时间的信息180                     int year = end_Time.Value.Year;181                     int month = end_Time.Value.Month;182                     int day = end_Time.Value.Day;183 184                     int hour = end_Time.Value.Hour;185                     int minute = end_Time.Value.Minute;186                     int second = end_Time.Value.Second;187 188                     // 当时分秒均为0时,为结束时间加上时分秒189                     if (hour == 0 && minute == 0 && second == 0) {190                         DateTime now = DateTime.Now;191                         // 若结束时间的年月日正好是当天192                         if (now.Year == year && now.Month == month && now.Day == day)193                             end_Time = now;194                         // 否则,给到结束时间那天,最后一秒195                         else196                             end_Time = new DateTime(year, month, day, 23, 59, 59);197                     }198                 }199 200                 return end_Time;201             }202             set { end_Time = value; }203         }204 205         #endregion206 207         #region 时间输出208 209         /// 210         /// 时间字符串返回格式211         /// 若不设置,默认为"yyyy-MM-dd HH:mm:ss"212         /// 213         public string Format {214             get {215                 if (format == null)216                     format = "yyyy-MM-dd HH:mm:ss";217                 return format;218             }219             set { format = value; }220         }221         private string format;222 223         /// 224         /// 用于返回开始时间字符串225         /// 226         public string GetStarTimeStr {227             get {228                 if (Start_Time.HasValue)229                     return Start_Time.Value.ToString(Format);230                 return "";231             }232         }233 234         /// 235         /// 用于返回结束时间字符串236         /// 237         public string GetEndTimeStr {238             get {239                 if (End_Time.HasValue)240                     return End_Time.Value.ToString(Format);241                 return "";242             }243         }244 245         #endregion246 247         #endregion248 249         #endregion250 251         #region 校验方法252 253         /// 254         /// 保证num的值范围为,[min,max]255         /// 256         /// 原始数据257         /// 最小值258         /// 最大值259         /// 默认值(不填时,默认值为最小值)260         /// 
261 public int? GetNumInMinToMax(ref int? num, int min, int max, int? def = null) {262 // 若def没有值,将最小值给它263 if (!def.HasValue)264 def = min;265 // 若num没有值,将默认值给它266 if (!num.HasValue)267 num = def;268 // 若num的值小于最小值,或大于最大值,将默认值给它269 else if (num < min || max < num)270 num = def;271 272 return num;273 }274 275 /// 276 /// 将字符串去掉空格,并进行敏感字符检测277 /// 278 /// 原字符串279 /// 是否开启敏感字符校验280 /// 默认的值,字符串为空时,赋此值281 ///
282 public string CheckStr(ref string str, bool Ischeck = true,string def="") {283 if (string.IsNullOrEmpty(str))284 return str = def;285 str = str.Trim();286 if (Ischeck)287 if (!GetIsFormText(str))288 str = "请不要输入敏感字符!";289 return str;290 }291 292 /// 293 /// 检测是否含有危险字符(防止Sql注入)294 /// 转自:http://blog.csdn.net/chaozi/article/details/4462312295 /// 296 /// 预检测的内容297 ///
返回True或false
298 public static bool GetIsFormText(string contents) {299 bool bReturnValue = false;300 if (contents.Length > 0) {301 //convert to lower302 string sLowerStr = contents.ToLower();303 //RegularExpressions304 string sRxStr = "(/sand/s)|(/sand/s)|(/slike/s)|(select/s)|(insert/s)|" +305 "(delete/s)|(update/s[/s/S].*/sset)|(create/s)|(/stable)|(<[iframe|/iframe|" +306 "script|/script])|(')|(/sexec)|(/sdeclare)|(/struncate)|(/smaster)|(/sbackup)|(/smid)|(/scount)";307 //Match308 bool bIsMatch = false;309 System.Text.RegularExpressions.Regex sRx = new310 311 System.Text.RegularExpressions.Regex(sRxStr);312 bIsMatch = sRx.IsMatch(sLowerStr, 0);313 if (bIsMatch) {314 bReturnValue = true;315 }316 }317 return bReturnValue;318 }319 320 #endregion321 322 #region 数据绑定方法323 324 /// 325 /// 返回指定区间的日期,默认今天326 /// 327 /// 328 public void GetDateSection(DateSection dateSection = DateSection.Today) {329 330 // 判断枚举中,是否存在此项331 if (!Enum.IsDefined(typeof(DateSection), (int)dateSection))332 dateSection = DateSection.Today;333 334 // 日期335 DateTime Date = DateTime.Now;336 337 // 倒退的天数338 int BackDay = 0;339 340 switch (dateSection) {341 342 #region =====今天=====343 344 case DateSection.Today:345 End_Time = Date;346 Start_Time = new DateTime(Date.Year, Date.Month, Date.Day, 0, 0, 0, 0);347 break;348 349 #endregion350 351 #region =====昨天=====352 353 case DateSection.Yesterday:354 Date = DateTime.Now.AddDays(-1);355 356 End_Time = new DateTime(Date.Year, Date.Month, Date.Day, 23, 59, 59, 999);357 Start_Time = new DateTime(Date.Year, Date.Month, Date.Day, 0, 0, 0, 0, 0);358 break;359 360 #endregion361 362 #region =====本周=====363 364 case DateSection.ThisWeek:365 End_Time = Date;366 367 // 获取今天是本周第几天368 BackDay = Convert.ToInt32(Date.DayOfWeek.ToString("d"));369 370 Date = DateTime.Now.AddDays(-BackDay);371 Start_Time = new DateTime(Date.Year, Date.Month, Date.Day, 0, 0, 0, 0);372 break;373 374 #endregion375 376 #region =====上周=====377 378 case DateSection.LastWeek:379 BackDay = Convert.ToInt32(Date.DayOfWeek.ToString("d")) + 1;380 381 // 到上周最后一天382 Date = DateTime.Now.AddDays(-BackDay);383 End_Time = new DateTime(Date.Year, Date.Month, Date.Day, 23, 59, 59, 999);384 385 // 到上周第一天386 Date = Date.AddDays(-6);387 Start_Time = new DateTime(Date.Year, Date.Month, Date.Day, 0, 0, 0, 0);388 389 break;390 391 #endregion392 393 #region =====本月=====394 395 case DateSection.ThisMonth:396 End_Time = Date;397 Start_Time = new DateTime(Date.Year, Date.Month, 1, 0, 0, 0, 0);398 break;399 400 #endregion401 402 #region =====上月=====403 404 case DateSection.LastMonth:405 406 BackDay = Date.Day;407 408 // 到上月最后一天409 Date = DateTime.Now.AddDays(-BackDay);410 End_Time = new DateTime(Date.Year, Date.Month, Date.Day, 23, 59, 59, 999);411 412 Start_Time = new DateTime(Date.Year, Date.Month, 1, 0, 0, 0, 0);413 break;414 415 #endregion416 417 #region =====今年=====418 419 case DateSection.ThisYear:420 End_Time = Date;421 Start_Time = new DateTime(Date.Year, 1, 1, 0, 0, 0, 0);422 break;423 424 #endregion425 426 #region =====去年=====427 428 case DateSection.LastYear:429 BackDay = Date.DayOfYear;430 431 // 到去年最后一天432 Date = DateTime.Now.AddDays(-BackDay);433 End_Time = new DateTime(Date.Year, Date.Month, Date.Day, 23, 59, 59, 999);434 435 Start_Time = new DateTime(Date.Year, 1, 1, 0, 0, 0, 0);436 break;437 438 #endregion439 440 default: break;441 }442 443 }444 445 /// 446 /// 保证开始和结束时间绝对不为空447 /// 448 /// 间隔长度,默认:7449 /// 间隔单位,默认:Day(天)450 public void GetDateNow(int DateLong = 7, DateFormat dateFormat = DateFormat.Day) {451 452 // 校验是否存在此枚举453 if (Enum.IsDefined(typeof(DateFormat), (int)dateFormat))454 dateFormat = DateFormat.Day;455 456 // 初始化结束时间457 if (End_Time == null)458 End_Time = DateTime.Now;459 460 DateTime? star;461 462 // 有校验的时间463 star = new DateTime();464 star = Start_Time;465 ChangStar(ref star, End_Time, DateLong, dateFormat);466 Start_Time = star;467 468 }469 470 /// 471 /// 根据结束时间,修改开始时间472 /// 若开始时间有值,则不改动473 /// 474 /// 开始时间475 /// 结束时间476 /// 间隔长度477 /// 间隔单位478 private void ChangStar(ref DateTime? Start, DateTime? End, int DateLong, DateFormat dateFormat) {479 480 if (Start.HasValue)481 return;482 483 DateLong = 0 - DateLong;484 485 // 获取开始时间486 switch (dateFormat) {487 // 年份488 case DateFormat.Year:489 Start = End.Value.AddYears(DateLong);490 break;491 // 月份492 case DateFormat.Month:493 Start = End.Value.AddMonths(DateLong);494 break;495 // 天数496 case DateFormat.Day:497 Start = End.Value.AddDays(DateLong);498 break;499 // 小时500 case DateFormat.Hour:501 Start = End.Value.AddHours(DateLong);502 break;503 // 分钟504 case DateFormat.Minute:505 Start = End.Value.AddMinutes(DateLong);506 break;507 // 秒钟508 case DateFormat.Second:509 Start = End.Value.AddSeconds(DateLong);510 break;511 }512 513 }514 515 #endregion516 }517 518 /// 519 /// 时间格式520 /// 521 public enum DateFormat {522 /// 523 /// 年份524 /// 525 Year,526 /// 527 /// 月份528 /// 529 Month,530 /// 531 /// 天数532 /// 533 Day,534 /// 535 /// 小时536 /// 537 Hour,538 /// 539 /// 分钟540 /// 541 Minute,542 /// 543 /// 秒钟544 /// 545 Second546 }547 548 /// 549 /// 时间区间550 /// 551 public enum DateSection {552 /// 553 /// 今天554 /// 555 Today,556 /// 557 /// 昨天558 /// 559 Yesterday,560 /// 561 /// 本周,星期天为第一天562 /// 563 ThisWeek,564 /// 565 /// 上周,星期天为第一天566 /// 567 LastWeek,568 /// 569 /// 本月570 /// 571 ThisMonth,572 /// 573 /// 上月574 /// 575 LastMonth,576 /// 577 /// 今年578 /// 579 ThisYear,580 /// 581 /// 去年582 /// 583 LastYear584 }585 586 }
View Code

 

个人觉着,虽然代码一般般,但里面有不少小技巧还是很不错的,适合那些比我还新的新手学习一下,比如时间校验,,那个真的是伤透了心

如果大家发现了有什么bug,欢迎指出,或者有比较有趣的点子也欢迎互相交流,,,嗯,就酱紫,我去纠结TreeView控件绑值的问题,,

 

转载于:https://www.cnblogs.com/Onlooker/p/7587696.html

你可能感兴趣的文章
安装Git
查看>>
设置启动图片LaunchScreen 和 LaunchImage
查看>>
L84
查看>>
L157
查看>>
L156
查看>>
第十周作业
查看>>
win10常用快捷键
查看>>
vmware搭建vSAN提示磁盘不合格或者看不到磁盘的解决办法
查看>>
HashMap和Hashtable的区别
查看>>
Oracle EBS-SQL (INV-5):检查期间拉式物料领用记录数.sql
查看>>
Python之with语句原理
查看>>
在Window环境下多线程与CPU资源分配原则
查看>>
20170303新的开始
查看>>
Python--day25--复习(单继承和多继承的总结)
查看>>
@Html.EditFor()不能添加“只读”html属性;以及disable属性的坑
查看>>
Logger日志级别说明及设置方法、说明
查看>>
7-1 列出连通集 (25 分)
查看>>
Mybatis之Mapper动态代理
查看>>
【转】楼天城楼教主的acm心路历程(作为励志用)
查看>>
vw、vh、vmin、vmax 的含义
查看>>