2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > (转)一步一步Asp.Net MVC系列_权限管理之权限控制

(转)一步一步Asp.Net MVC系列_权限管理之权限控制

时间:2024-07-26 21:06:04

相关推荐

(转)一步一步Asp.Net MVC系列_权限管理之权限控制

原文地址:/mysweet/archive//08/05/2623687.html

在权限管理中一个很重要的就是关于权限的拦截验证问题,特别是我们在webform中的验证,比纯winform要更复杂,winform可以通过验证把按钮隐藏或者禁用的方式,但是在web中我们不能仅仅通过隐藏按钮,不显示菜单/按钮之类的手段,因为客户端的代码都是透明的,如果我们不在服务端把好关,那么权限根本就无从谈起,我们必须彻底的进行验证,每一步动作都要进行验证,客户端的每一个ajax提交都要进行验证,如果任何一个ajax 动作都做过验证了,那么至少可以保证基本的安全性了.

在纯webform中,我们通常怎么来进行权限控制呢?

一般情况下,设计基类然后,在基类写好验证方法,子类调用并验证

我们来看看启航动力的开源CMS怎么进行的验证:

1: using System;

2: using System.Collections.Generic;

3: using System.Text;

4: using System.Web;

5: using System.Web.UI.WebControls;

6: using mon;

7:

8: namespace DTcms.Web.UI

9: {

10:public class ManagePage : System.Web.UI.Page

11:{

12:protected internal Model.siteconfig siteConfig;

13:

14:public ManagePage()

15:{

16: this.Load += new EventHandler(ManagePage_Load);

17: siteConfig = new BLL.siteconfig().loadConfig(Utils.GetXmlMapPath("Configpath"));

18:}

19:

20:private void ManagePage_Load(object sender, EventArgs e)

21:{

22: //判断管理员是否登录

23: if (!IsAdminLogin())

24: {

25: Response.Write("<script>parent.location.href='" + siteConfig.webpath + siteConfig.webmanagepath + "/login.aspx'</script>");

26: Response.End();

27: }

28:}

29:

30:#region 管理员============================================

31:/// <summary>

32:/// 判断管理员是否已经登录(解决Session超时问题)

33:/// </summary>

34:public bool IsAdminLogin()

35:{

36: //如果Session为Null

37: if (Session[DTKeys.SESSION_ADMIN_INFO] != null)

38: {

39: return true;

40: }

41: else

42: {

43: //检查Cookies

44: string adminname = Utils.GetCookie("AdminName", "DTcms"); //解密用户名

45: string adminpwd = Utils.GetCookie("AdminPwd", "DTcms");

46: if (adminname != "" && adminpwd != "")

47: {

48: BLL.manager bll = new BLL.manager();

49: Model.manager model = bll.GetModel(adminname, adminpwd);

50: if (model != null)

51: {

52:Session[DTKeys.SESSION_ADMIN_INFO] = model;

53:return true;

54: }

55: }

56: }

57: return false;

58:}

59:

60:/// <summary>

61:/// 取得管理员信息

62:/// </summary>

63:public Model.manager GetAdminInfo()

64:{

65: if (IsAdminLogin())

66: {

67: Model.manager model = Session[DTKeys.SESSION_ADMIN_INFO] as Model.manager;

68: if (model != null)

69: {

70: return model;

71: }

72: }

73: return null;

74:}

75:

76:/// <summary>

77:/// 检查管理员权限

78:/// </summary>

79:/// <param name="channel_id">频道ID</param>

80:/// <param name="action_type">操作类型</param>

81:public void ChkAdminLevel(int channel_id, string action_type)

82:{

83: Model.manager model = GetAdminInfo();

84: BLL.manager_role bll = new BLL.manager_role();

85: bool result = bll.Exists(model.role_id, channel_id, action_type);

86: if (!result)

87: {

88: string msbox = "parent.f_errorTab(\"错误提示\", \"您没有管理该页面的权限,请勿尝试非法进入!\")";

89: //ClientScript.RegisterClientScriptBlock(Page.GetType(), "JsPrint", msbox.ToString(), true); //修正BUG

90: Response.Write("<script type=\"text/javascript\">" + msbox + "</script>");

91: Response.End();

92: }

93:}

94:

95:/// <summary>

96:/// 检查管理员权限

97:/// </summary>

98:/// <param name="channel_name">栏目名称</param>

99:/// <param name="action_type">操作类型</param>

100:public void ChkAdminLevel(string channel_name, string action_type)

101:{

102: Model.manager model = GetAdminInfo();

103: BLL.manager_role bll = new BLL.manager_role();

104: bool result = bll.Exists(model.role_id, channel_name, action_type);

105: if (!result)

106: {

107: string msbox = "parent.f_errorTab(\"错误提示\", \"您没有管理该页面的权限,请勿尝试非法进入!\")";

108: //ClientScript.RegisterClientScriptBlock(Page.GetType(), "JsPrint", msbox.ToString(), true); //修正BUG

109: Response.Write("<script type=\"text/javascript\">" + msbox + "</script>");

110: Response.End();

111: }

112:}

113:

114:/// <summary>

115:/// 检查管理员权限

116:/// </summary>

117:/// <param name="channel_name">栏目名称</param>

118:/// <param name="action_type">操作类型</param>

119:/// <returns>bool</returns>

120:public bool IsAdminLevel(string channel_name, string action_type)

121:{

122: Model.manager model = GetAdminInfo();

123: BLL.manager_role bll = new BLL.manager_role();

124: return bll.Exists(model.role_id, channel_name, action_type);

125:}

126:

127:#endregion

128:

129:#region 枚举==============================================

130:

131:/// <summary>

132:/// 统一管理操作枚举

133:/// </summary>

134:public enum ActionEnum

135:{

136: /// <summary>

137: /// 所有

138: /// </summary>

139: All,

140: /// <summary>

141: /// 查看

142: /// </summary>

143: View,

144: /// <summary>

145: /// 添加

146: /// </summary>

147: Add,

148: /// <summary>

149: /// 修改

150: /// </summary>

151: Edit,

152: /// <summary>

153: /// 删除

154: /// </summary>

155: Delete

156:}

157:

158:/// <summary>

159:/// 属性类型枚举

160:/// </summary>

161:public enum AttributeEnum

162:{

163: /// <summary>

164: /// 输入框

165: /// </summary>

166: Text,

167: /// <summary>

168: /// 下拉框

169: /// </summary>

170: Select,

171: /// <summary>

172: /// 单选框

173: /// </summary>

174: Radio,

175: /// <summary>

176: /// 复选框

177: /// </summary>

178: CheckBox

179:}

180:#endregion

181:

182:#region JS提示============================================

183:

184:/// <summary>

185:/// 添加编辑删除提示

186:/// </summary>

187:/// <param name="msgtitle">提示文字</param>

188:/// <param name="url">返回地址</param>

189:/// <param name="msgcss">CSS样式</param>

190:protected void JscriptMsg(string msgtitle, string url, string msgcss)

191:{

192: string msbox = "parent.jsprint(\"" + msgtitle + "\", \"" + url + "\", \"" + msgcss + "\")";

193: ClientScript.RegisterClientScriptBlock(Page.GetType(), "JsPrint", msbox, true);

194:}

195:

196:/// <summary>

197:/// 带回传函数的添加编辑删除提示

198:/// </summary>

199:/// <param name="msgtitle">提示文字</param>

200:/// <param name="url">返回地址</param>

201:/// <param name="msgcss">CSS样式</param>

202:/// <param name="callback">JS回调函数</param>

203:protected void JscriptMsg(string msgtitle, string url, string msgcss, string callback)

204:{

205: string msbox = "parent.jsprint(\"" + msgtitle + "\", \"" + url + "\", \"" + msgcss + "\", " + callback + ")";

206: ClientScript.RegisterClientScriptBlock(Page.GetType(), "JsPrint", msbox, true);

207:}

208:#endregion

209:

210:}

211: }

在子类校验的时候继承ManagePage的基类,然后就这样校验:

可以看到这种是通常的设计方案,基类定义,子类校验,不过这个启航动力CMS,他完全是在基类定义枚举,控制仅仅停留在增删改查,浏览,这些,不过CMS确实这一层就可以了,而且它的设计感觉不太好,因为到处都是验证代码,每一个增删改查方法都有这些验证的代码,如果是我我就会用委托的方式绑定方法,在Page_Load里面验证权限,委托绑定增删改查方法,这样,把验证的过程大大节省,这些甚至可以设计成公共的方法,来实现.

我们今天讲解的是MVC里面的权限验证,MVC天然的Controller,Action,让我们的权限控制更加容易,而且更简洁,更清晰.

首先,先来看看,MVC里面的一个小特色设计:

这个是一个普通的model,在mvc示例项目中,他采用Attribute方式来验证,我当时看到的时候感觉耳目一新,以前看<<CLR VIA C#>> Attribute的时候,当时还在想这些东西可以干什么??仅仅是元数据描述??后来才发现,这东西太强大了,控件的设计,反射,ORM,无处不在,Attributes也让代码更加优雅.

我们可以在mvc中定义各种Attribute来让我们的代码更优雅,而且让权限更简洁,比如我们经常会设计,

xxxx页面登录后才能访问,

xxxxx页面匿名用户也能访问,

xxxx页面必须经过权限验证才能访问,

xxxxx各种类型

我们可以定义各种Attribute来描述它,这种描述也让权限控制更加优雅.

比如:我们有几个登录页面,错误显示页面等等,这些页面,可以单独设计一个Attribute标记来标识.

我们可以定义各种各样的标记来描述权限控制,

可以看到我们在这里只需要标记匿名标记,然后在权限拦截中进行处理,如果存在Anonymous标记就默认允许.

这里在公共基类中设计验证标记,子类继承,这样,我们就可以达到子类全部都需要验证处理..

接下来,我们就看看,我们的权限拦截如何处理的.

我们的权限拦截是通过继承ActionFilterAttribute,自定义拦截器,这里参考传说中弦哥的思路.

简单地说,ActionFilter就是Action过滤器,任何一个请求都像筛子一样的过滤.所以,这个Filter就是筛子,我们需要的就是在这个筛子上做权限控制,这样我们的权限不就容易得多了么?

这时候,我想到了以前的一张生命周期,一个请求过来同样经过了HttpModule等一层层,在那里做权限拦截,可能效果更好,如果webform设计,可能要尝试一下看看能不能这么做.

1: /// <summary>

2:/// 权限拦截

3:/// </summary>

4:[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]

5:public class PermissionFilterAttribute : ActionFilterAttribute

6:{

7:/// <summary>

8:/// 权限拦截

9:/// </summary>

10:/// <param name="filterContext"></param>

11:public override void OnActionExecuting(ActionExecutingContext filterContext)

12:{

13: //权限拦截是否忽略

14: bool IsIgnored = false;

15: if (filterContext == null)

16: {

17: throw new ArgumentNullException("filterContext");

18: }

19: var path = filterContext.HttpContext.Request.Path.ToLower();

20: //获取当前配置保存起来的允许页面

21: IList<string> allowPages = ConfigSettings.GetAllAllowPage();

22: foreach (string page in allowPages)

23: {

24: if (page.ToLower() == path)

25: {

26: IsIgnored = true;

27: break;

28: }

29: }

30: if (IsIgnored)

31: return;

32: //接下来进行权限拦截与验证

33: object[] attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(ViewPageAttribute), true);

34: var isViewPage = attrs.Length == 1;//当前Action请求是否为具体的功能页

35:

36: if (this.AuthorizeCore(filterContext) == false)//根据验证判断进行处理

37: {

38: //注:如果未登录直接在URL输入功能权限地址提示不是很友好;如果登录后输入未维护的功能权限地址,那么也可以访问,这个可能会有安全问题

39: if (isViewPage == true)

40: {

41: //跳转到登录页面

42: filterContext.RequestContext.HttpContext.Response.Redirect("~/Admin/Manage/UserLogin");

43: }

44: else

45: {

46:

47: //跳转到登录页面

48: filterContext.RequestContext.HttpContext.Response.Redirect("~/Admin/Manage/Error");

49: }

50: }

51:}

这个Attribute直接借鉴的弦哥的模型,

这样我们可以对程序进行细化的处理过程.

针对不同的标记进行处理:

1: /// <summary>

2:/// [Anonymous标记]验证是否匿名访问

3:/// </summary>

4:/// <param name="filterContext"></param>

5:/// <returns></returns>

6:public bool CheckAnonymous(ActionExecutingContext filterContext)

7:{

8: //验证是否是匿名访问的Action

9: object[] attrsAnonymous = filterContext.ActionDescriptor.GetCustomAttributes(typeof(AnonymousAttribute), true);

10: //是否是Anonymous

11: var Anonymous = attrsAnonymous.Length == 1;

12: return Anonymous;

13:}

14:/// <summary>

15:/// [LoginAllowView标记]验证是否登录就可以访问(如果已经登陆,那么不对于标识了LoginAllowView的方法就不需要验证了)

16:/// </summary>

17:/// <param name="filterContext"></param>

18:/// <returns></returns>

19:public bool CheckLoginAllowView(ActionExecutingContext filterContext)

20:{

21: //在这里允许一种情况,如果已经登陆,那么不对于标识了LoginAllowView的方法就不需要验证了

22: object[] attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(LoginAllowViewAttribute), true);

23: //是否是LoginAllowView

24: var ViewMethod = attrs.Length == 1;

25: return ViewMethod;

26:}

27:

28:/// <summary>

29:/// //权限判断业务逻辑

30:/// </summary>

31:/// <param name="filterContext"></param>

32:/// <param name="isViewPage">是否是页面</param>

33:/// <returns></returns>

34:protected virtual bool AuthorizeCore(ActionExecutingContext filterContext)

35:{

36:

37: if (filterContext.HttpContext == null)

38: {

39: throw new ArgumentNullException("httpContext");

40: }

41: //验证当前Action是否是匿名访问Action

42: if (CheckAnonymous(filterContext))

43: return true;

44: //未登录验证

45: if (SessionHelper.Get("UserID") == null)

46: {

47: return false;

48: }

49: //验证当前Action是否是登录就可以访问的Action

50: if (CheckLoginAllowView(filterContext))

51: return true;

52:

53: //下面开始用户权限验证

54: var user = new UserService();

55: SysCurrentUser CurrentUser = new SysCurrentUser();

56: var controllerName = filterContext.RouteData.Values["controller"].ToString();

57: var actionName = filterContext.RouteData.Values["action"].ToString();

58: //如果是超级管理员,直接允许

59: if (CurrentUser.UserID == ConfigSettings.GetAdminUserID())

60: {

61: return true;

62: }

63: //如果拥有超级管理员的角色就默认全部允许

64: string AdminUserRoleID = ConfigSettings.GetAdminUserRoleID().ToString();

65: //检查当前角色组有没有超级角色

66: if (Tools.CheckStringHasValue(CurrentUser.UserRoles, ',', CurrentUser.UserRoles))

67: {

68: return true;

69: }

70:

71: //Action权限验证

72: if (controllerName.ToLower() != "manage")//如果当前Action请求为具体的功能页并且不是Manage中 Index页和Welcome页

73: {

74: //验证

75: if (!user.RoleHasOperatePermission(CurrentUser.UserRoles, controllerName, actionName))//如果验证该操作是否拥有权限

76: {

77: return false;

78: }

79: }

80: //管理页面直接允许

81: return true;

82:}

可以看到我们仅仅这一个PermissionAttribute配合其他的Attribute就实现了权限的拦截控制.

当然,我们仍然需要配置那些东西?

过滤页面.....

有一些页面我们可以直接配置允许访问的页面:

1: var path = filterContext.HttpContext.Request.Path.ToLower();

2: //获取当前配置保存起来的允许页面

3: IList<string> allowPages = ConfigSettings.GetAllAllowPage();

4: foreach (string page in allowPages)

5: {

6: if (page.ToLower() == path)

7: {

8: IsIgnored = true;

9: break;

10: }

11: }

12: if (IsIgnored)

13: return;

我们在自定义配置文件中,可以定义允许访问的页面,比如:错误页之类的,可能有些人觉得,不需要,但是这个配置是在程序发布以后,仍然能够很轻松的进行配置,所以,预留一个配置页面还是蛮有必要的.

同时我们也需要配置超级管理员身份和角色....

有人觉得,这些需要么?

我觉得是需要的,因为数据库读取出来的角色,根本没办法分辨超级管理员,只能数据库动态配置,我们就预定义这样的一个超级管理员角色的身份ID,让这个超级管理角色拥有任何的功能和任何的权限,甚至读取数据库的时候,都是读取的所有模块权限,菜单权限.

这样我们的配置工作就非常简单了,特别是数据库没有大部分配置初试信息(比如菜单信息,角色信息,)的时候,我们不需要手动往数据库添加数据,直接在程序中添加就可以了,也算是一个超级管理员身份.

接下来,我们的权限控制基本上就差不多了,现在我们可以安心的写页面了,权限神马东西,跟咱关系就不大了,这样,分工不是更爽,干别人的活才是最纠结的.......

接下来,我们可以继续设计一些公共类来简化我们日常的操作,对于公共类的设计,我觉得要拿出最大的热情与态度,要知道这些是能够真正节省我们时间的东西.

只有设计好它,我们以后才会更快更爽更轻松.

我们经常会遇到这样的代码:

1: /// <summary>

2:/// 保存资料业务

3:/// </summary>

4:/// <param name="context"></param>

5:public void SaveCompany(HttpContext context)

6:{

7://用户json数据读取

8:company Info=new company ();

9:String CompanyStr = context.Request["Company"];

10:string id=context.Request["id"];

11:string pic = context.Request["pic"];

12:if (!Tools.IsValidInput(ref pic, true) || !Tools.IsValidInput(ref id, true))

13:{

14: return;

15:}

16: //图片保存

17://System.IO.StreamWriter sw = new System.IO.StreamWriter(context.Server.MapPath("tzt.txt"), true);

18://sw.Write(CompanyStr);

19://sw.Close();

20://使用Newtonsoft.Json.dll组件解析json对象

21:

22:JObject o = JObject.Parse(CompanyStr);

23:Info.Username = (string)o.SelectToken("Username");

24:if (!new companyBLL().CheckExistUserName(Info.Username))

25:{

26: context.Response.Write(false);

27: return;

28:}

29:Info.Password = (string)o.SelectToken("Password");

30:Info.Name = (string)o.SelectToken("Name");

31:Info.Isrecommend = ((string)o.SelectToken("Isrecommend"))=="true" ? "1" : "0";

32:Info.Fac = (string)o.SelectToken("Fac");

33:Info.Representative = (string)o.SelectToken("Representative");

34:Info.Isshow = ((string)o.SelectToken("Isshow")) == "true" ? "1" : "0";

35:Info.State = ((string)o.SelectToken("State")) == "true" ? "1" : "0";

36:Info.State1 = ((string)o.SelectToken("State1")) == "true" ? "1" : "0";

37:

38:Info.Zipcode = (string)o.SelectToken("Zipcode");

39:Info.QQ = (string)o.SelectToken("QQ");

40:Info.Telephone = (string)o.SelectToken("Telephone");

41:Info.mobilephone = (string)o.SelectToken("mobilephone");

42:Info.Email = (string)o.SelectToken("Email");

43:Info.Address = (string)o.SelectToken("Address");

44:Info.Website = (string)o.SelectToken("Website");

45:Info.Award = (string)o.SelectToken("Award");

46:Info.Introduction = (string)o.SelectToken("Introduction");

47:Info.Picturepath = pic;

48:

49:if (!string.IsNullOrEmpty(id))

50: Info.Id = Convert.ToInt32(id);

51:

52:if (!Info.Id.HasValue)

53:{

54: Info.rank = 0;

55: Info.hit = 0;

56: //执行增加操作

57: new companyBLL().AddNew(Info);

58: SMTP smtp = new SMTP(Info.Email);

59: string webpath = context.Request.Url.Scheme + "://" + context.Request.Url.Authority + System.Web.VirtualPathUtility.ToAbsolute("~/Default.aspx");

60: smtp.Activation(webpath, Info.Name);//发送激活邮件

61:}

62:else

63:{

64: new companyBLL().Update(Info);

65:}

66:

67:

68:}

这是我以前一个电子商务网站项目写的,

我现在看,简直到处都是毛病.......

首先,关于form读取内容占了一大块.......

可以想象,到处都是赋值语句,看到都吐血,再加上一些验证非空,验证函数等等,更是罪加一等的恶劣.

当然我们需要一步一步的解决这些问题,首先是剥离关于表单读取的内容,封装到一个类中,然后在类中进行验证处理.

权限验证中的样例,

验证也没有做大块的处理,不过大家可以注意,可以看到想当的简洁,我们同时需要各种辅助类的设计,强制转化的处理,非空验证的处理,等等,我们直接设计成扩展方法就能达到上图中ObjToIntNULL()的形式, 也不需要ConvertToInt32(xxxxx)的形式来转化了,不是更简洁么?

1: /* 作者: tianzh

2: * 创建时间: /7/22 15:38:20

3: *

4: */

5: using System;

6: using System.Collections.Generic;

7: using System.Linq;

8: using System.Text;

9:

10: namespace mon

11: {

12:/// <summary>

13:/// 强制转化辅助类(无异常抛出)

14:/// </summary>

15:public static class ConvertHelper

16:{

17:#region 强制转化

18:/// <summary>

19:/// object转化为Bool类型

20:/// </summary>

21:/// <param name="obj"></param>

22:/// <returns></returns>

23:public static bool ObjToBool(this object obj)

24:{

25: bool flag;

26: if (obj == null)

27: {

28: return false;

29: }

30: if (obj.Equals(DBNull.Value))

31: {

32: return false;

33: }

34: return (bool.TryParse(obj.ToString(), out flag) && flag);

35:}

36:/// <summary>

37:/// object强制转化为DateTime类型(吃掉异常)

38:/// </summary>

39:/// <param name="obj"></param>

40:/// <returns></returns>

41:public static DateTime? ObjToDateNull(this object obj)

42:{

43: if (obj == null)

44: {

45: return null;

46: }

47: try

48: {

49: return new DateTime?(Convert.ToDateTime(obj));

50: }

51: catch (ArgumentNullException ex)

52: {

53: return null;

54: }

55:}

56:/// <summary>

57:/// int强制转化

58:/// </summary>

59:/// <param name="obj"></param>

60:/// <returns></returns>

61:public static int ObjToInt(this object obj)

62:{

63: if (obj != null)

64: {

65: int num;

66: if (obj.Equals(DBNull.Value))

67: {

68: return 0;

69: }

70: if (int.TryParse(obj.ToString(), out num))

71: {

72: return num;

73: }

74: }

75: return 0;

76:}

77:/// <summary>

78:/// 强制转化为long

79:/// </summary>

80:/// <param name="obj"></param>

81:/// <returns></returns>

82:public static long ObjToLong(this object obj)

83:{

84: if (obj != null)

85: {

86: long num;

87: if (obj.Equals(DBNull.Value))

88: {

89: return 0;

90: }

91: if (long.TryParse(obj.ToString(), out num))

92: {

93: return num;

94: }

95: }

96: return 0;

97:}

98:/// <summary>

99:/// 强制转化可空int类型

100:/// </summary>

101:/// <param name="obj"></param>

102:/// <returns></returns>

103:public static int? ObjToIntNull(this object obj)

104:{

105: if (obj == null)

106: {

107: return null;

108: }

109: if (obj.Equals(DBNull.Value))

110: {

111: return null;

112: }

113: return new int?(ObjToInt(obj));

114:}

115:/// <summary>

116:/// 强制转化为string

117:/// </summary>

118:/// <param name="obj"></param>

119:/// <returns></returns>

120:public static string ObjToStr(this object obj)

121:{

122: if (obj == null)

123: {

124: return "";

125: }

126: if (obj.Equals(DBNull.Value))

127: {

128: return "";

129: }

130: return Convert.ToString(obj);

131:}

132:/// <summary>

133:/// Decimal转化

134:/// </summary>

135:/// <param name="obj"></param>

136:/// <returns></returns>

137:public static decimal ObjToDecimal(this object obj)

138:{

139: if (obj == null)

140: {

141: return 0M;

142: }

143: if (obj.Equals(DBNull.Value))

144: {

145: return 0M;

146: }

147: try

148: {

149: return Convert.ToDecimal(obj);

150: }

151: catch

152: {

153: return 0M;

154: }

155:}

156:/// <summary>

157:/// Decimal可空类型转化

158:/// </summary>

159:/// <param name="obj"></param>

160:/// <returns></returns>

161:public static decimal? ObjToDecimalNull(this object obj)

162:{

163: if (obj == null)

164: {

165: return null;

166: }

167: if (obj.Equals(DBNull.Value))

168: {

169: return null;

170: }

171: return new decimal?(ObjToDecimal(obj));

172:}

173:#endregion

174:

175:}

176: }

一些好的常用的扩展方法同样是一个相当大的改进,对于代码,也更清晰,更简洁,我们同时可以设计一些非空验证等等.

1: #region 判断对象是否为空

2:/// <summary>

3:/// 判断对象是否为空,为空返回true

4:/// </summary>

5:/// <typeparam name="T">要验证的对象的类型</typeparam>

6:/// <param name="data">要验证的对象</param>

7:public static bool IsNullOrEmpty<T>(this T data)

8:{

9: //如果为null

10: if (data == null)

11: {

12: return true;

13: }

14:

15: //如果为""

16: if (data.GetType() == typeof(String))

17: {

18: if (string.IsNullOrEmpty(data.ToString().Trim())||data.ToString ()=="")

19: {

20: return true;

21: }

22: }

23:

24: //如果为DBNull

25: if (data.GetType() == typeof(DBNull))

26: {

27: return true;

28: }

29:

30: //不为空

31: return false;

32:}

33:

34:/// <summary>

35:/// 判断对象是否为空,为空返回true

36:/// </summary>

37:/// <param name="data">要验证的对象</param>

38:public static bool IsNullOrEmpty(this object data)

39:{

40: //如果为null

41: if (data == null)

42: {

43: return true;

44: }

45:

46: //如果为""

47: if (data.GetType() == typeof(String))

48: {

49: if (string.IsNullOrEmpty(data.ToString().Trim()))

50: {

51: return true;

52: }

53: }

54:

55: //如果为DBNull

56: if (data.GetType() == typeof(DBNull))

57: {

58: return true;

59: }

60:

61: //不为空

62: return false;

63:}

64:#endregion

这些东西其实真没有太多难的东西,只是简单的为了追求更简洁更方便而已,磨刀不误砍柴工就是这个道理,思考怎么偷懒才是程序员应该干的事情,不管多么忙都要停下来思考,想想怎么样才能偷懒!

界面上,不太会美工,直接照搬的LigerUI界面!

目前进度已经完成的差不多了,接下来要陆续总结学到的经验与技巧!

我的google code开源网站首页:/p/tzhsweetsourse/ 一直在努力,从未曾放弃,努力学习中..... 追逐吧!奔跑的少年! 拼搏吧!勇敢的心! 有梦想,就有希望! 为梦想而不懈奋斗着!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。