我们要搭建的框架是企业级开发框架,适用用企业管理信息系统的开发,如:OA、HR等
1、框架名称:sampleFrame。
2、搭建原则:最少知识原则。
3、先定义一个简单的编码规范:除类名和接口名外,其余首字母小写。
4、准备开发环境:vs2010及以上(mvc4)、sqlserver、jquery2.0和easyui1.4.5
首先来看一下列表页面的效果图:
我们期望简洁带前台代码,如下:
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
29
30
31
32
33
34
35
36
37
|
< table id = "dataGrid" class = "easyui-datagrid" url = "getList" toolbar = "#toolbar" > < thead > < tr > < th field = "customerId" sortable = "true" data-options = "sortable:true" width = "50" > customerId </ th > < th field = "companyName" data-options = "sortable:true" width = "50" > companyName </ th > < th field = "phone" width = "50" > phone </ th > < th field = "address" width = "50" > address </ th > </ tr > </ thead > </ table > < div id = "toolbar" > < div > < a class = "easyui-linkbutton" iconcls = "icon-add" onclick = "add();" >添加</ a > < a class = "easyui-linkbutton" iconcls = "icon-edit" onclick = "edit();" >修改</ a > < a class = "easyui-linkbutton" iconcls = "icon-remove" onclick = "del();" >删除</ a > </ div > < div > < input id = "queryBox" class = "easyui-textbox" buttonicon = "icon-search" style = "width: 200px;" data-options = "onClickButton:function(){loadList(loadListSettings);}" /> < a class = "easyui-linkbutton" iconcls = "icon-find" onclick = "showQueryWindow();" > 详细查询</ a > </ div > </ div > < script type = "text/javascript" > var loadListSettings = { searchFields: "customerId,companyName", prompt: "请输入客户Id或公司名称" }; </ script > < script type = "text/javascript" > pageInit(); </ script > |
为了这样简洁的前台,我们需要准备:
1、通用的布局模板_Layout.cshtml。base.css、base.js、defaultSettings.js、tool.js和private.js见后面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<!doctype html> < html > < head > < meta charset = "utf-8" /> < meta name = "viewport" content = "width=device-width" /> < meta http-equiv = "X-UA-Compatible" content = "IE=Edge,chrome=1" /> < link href = '/webResource/easyui/themes/default/easyui.css' rel = 'stylesheet' type = 'text/css' /> < link href = '/webResource/easyui/themes/icon.css' rel = 'stylesheet' type = 'text/css' /> < link href = '/webResource/base.css' rel = 'stylesheet' type = 'text/css' /> < script src = "/webResource/jquery/jquery.min.js" type = "text/javascript" ></ script > < script src = "/webResource/jquery/json2.js" type = "text/javascript" ></ script > < script src = "/webResource/easyui/jquery.easyui.min.js" type = "text/javascript" ></ script > < script src = "/webResource/easyui/locale/easyui-lang-zh_CN.js" type = "text/javascript" ></ script > < script src = "/webResource/tool.js" type = "text/javascript" ></ script > < script src = "/webResource/base.js" type = "text/javascript" ></ script > < script src = "/webResource/defaultSettings.js" type = "text/javascript" ></ script > < script src = "/webResource/private.js" type = "text/javascript" ></ script > @RenderSection("scripts", required: false) </ head > < body style = "width: 100%; height: 100%; margin: 0px;" > @RenderBody() </ body > </ html > |
2、平台样式表base.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
.icon-find { background : url ( 'icons/find.png' ) no-repeat center center ; } .datagrid-toolbar div:nth-child( 1 ) { float : left ; width : 60% ; } .datagrid-toolbar div:nth-child( 2 ) { margin-left : 60% ; margin-right : 10px ; width : auto ; text-align : right ; } |
3、基本方法脚本base.js
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
//取消自动渲染 $.parser.auto = false ; function pageInit() { //改变控件默认值 $.fn.linkbutton.defaults.plain = true ; $.fn.datagrid.defaults.fit = true ; $.fn.datagrid.defaults.fitColumns = true ; $.fn.datagrid.defaults.pagination = true ; //显示ajax异常信息 $(document).ajaxError( function (event, xhr, options, exc) { $.messager.alert({ title: '异步请求出错' , msg: xhr.responseText, icon: "error" }); }); //地址栏传参允许中文 jQuery(document).ajaxSend( function (event, request, options) { options.url = encodeURI(options.url); }); $.parser.parse(); } function loadList(settings) { var settings = $.extend( true , {}, loadListDefaultSettings, settings); if ($( "#" + settings.gridId).length == 0) $.messager.alert({ title: "系统异常" , msg: "DataGrid:" + settings.gridId + "不存在!" , icon: "error" }); var quickQueryData = []; if ($( "#" + settings.queryBoxId).length > 0) { var val = $( "#" + settings.queryBoxId).textbox( "getValue" ); if (settings.searchFields && val) { var keys = settings.searchFields.split( ',' ); for (i = 0, len = keys.length; i < len; i++) { quickQueryData.push({ field: keys[i], method: 'inLike' , value: val }); } } } var queryData = []; //详细查询预留 //加载数据 $( "#" + settings.gridId).datagrid( "load" , { quickQueryData: JSON.stringify(quickQueryData), queryData: JSON.stringify(queryData) }); } |
4、基本脚本默认值defaultSettings.js
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
//查询参数设置 var loadListDefaultSettings = { url: "getList" , gridId: "dataGrid" , queryWindowId: "queryWindow" , queryBoxId: "queryBox" , searchFields: "Name" , addQueryString: true , prompt: "请输入" }; 5、可能需要使用的工具方法tool.js //判断是否包含地址栏参数 function hasQueryString(key, url) { if ( typeof (url) == "undefined" ) url = window.location.search; var re = new RegExp( "[?&]" + key + "=([^\\&]*)" , "i" ); var a = re.exec(url); if (a == null ) return false ; return true ; } //获取地址栏参数,如果参数不存在则返回空字符串 function getQueryString(key, url) { if ( typeof (url) == "undefined" ) url = window.location.search; var re = new RegExp( "[?&]" + key + "=([^\\&]*)" , "i" ); var a = re.exec(url); if (a == null ) return "" ; return a[1]; } //将当前地址栏参数加入到url function addUrlSearch(url) { var newParams = []; var paramKeys = window.location.search.replace( '?' , '' ).split( '&' ); for ( var i = 0; i < paramKeys.length; i++) { var key = paramKeys[i].split( '=' )[0]; if (key == "" || key == "_t" || key == "_winid" || key == "isTab" ) continue ; if (!hasQueryString(key, url)) newParams.push(paramKeys[i]); } if (url.indexOf( '?' ) >= 0) return url + "&" + newParams.join( '&' ); else return url + "?" + newParams.join( '&' ); } //url增加参数 function addSearch(url, key, value) { if (!hasQueryString(key, url)) { if (url.indexOf( '?' ) >= 0) return url + "&" + key + "=" + value; else return url + "?" + key + "=" + value; } else return url; } //获取数组中对象的某个值,逗号分隔 function getValues(rows, attr) { var fieldValues = []; for ( var i = 0; i < rows.length; i++) { if (rows[i] != null ) fieldValues.push(rows[i][attr]); } return fieldValues.join( ',' ); } |
6、可能需要使用的私有方法private.js,此文件包含的方法专供base.js使用,开发web时禁止使用
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
//替换掉Url中的{}参数 function replaceUrl(settings, pty) { if (!pty) pty = "url" ; if (!settings[pty]) return ; var str = settings[pty]; var guid = "" ; var result = str.replace(/\{[0-9a-zA-Z_]*\}/g, function (e) { var key = e.substring(1, e.length - 1); if (key == "GUID" ) { if (!guid) { $.ajax({ url: "getGuid" , type: "post" , async: false , success: function (text, textStatus) { guid = text; } }); } return guid; } if (hasQueryString(key)) //从地址栏返回 return getQueryString(key); if (settings.currentRow && settings.currentRow[key]) //从当前行返回 return settings.currentRow[key]; if (settings.paramFrom) { //从指定控件返回 var ctrl = mini.get(settings.paramFrom); if (ctrl == undefined) { $.messager.alert({ title: 'UI出错' , msg: "Id为" + settings.paramFrom + "的控件不存在!" , icon: "error" }); return ; } else if (ctrl.showCheckBox) { return getValues(ctrl.getCheckedNodes(), key); } else if (ctrl.getSelecteds) return getValues(ctrl.getSelecteds(), key); else if (ctrl.getValue) return ctrl.getValue(); } return e; }); settings[pty] = result; return result; } //转化为全路径 function changeToFullUrl(settings) { var url = settings.url; return url; currentUrlPathName = window.location.pathname; var currentPathNameParts = currentUrlPathName.split( '/' ); var pathNameParts = url.split( '?' )[0].split( '/' ); if (currentPathNameParts[currentPathNameParts.length - 1] == "" ) currentPathNameParts.pop(); //去掉一个反斜线 if (pathNameParts[pathNameParts.length - 1] == "" ) pathNameParts.pop(); //去掉一个反斜线 var index = currentPathNameParts.length - 1; for ( var i = 0; i < pathNameParts.length; i++) { if (pathNameParts[i] == ".." ) { index = index - 1; if (index <= 0) { $.messager.alert({ title: "系统异常" , msg: "Url错误:" + url + "!" , icon: "error" }); return ; } continue ; } if (index < currentPathNameParts.length) currentPathNameParts[index] = pathNameParts[i]; else currentPathNameParts.push(pathNameParts[i]); index = index + 1; } var length = currentPathNameParts.length; for ( var i = index; i < length; i++) { currentPathNameParts.pop(); } var result = currentPathNameParts.join( '/' ); if (url.indexOf( '?' ) > 0) result += url.substring(url.indexOf( '?' )); settings.url = result; } |
我们期望简洁的后台代码,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using formula; using System.Data; namespace demo.Areas.basic.Controllers { public class customerController : BaseController { public JsonResult getList(QueryBuilder qb) { SqlHelper sqlHelper = new SqlHelper( "demo" ); var data = sqlHelper.ExecuteGridData( "select *,id=customerId from customer" , qb); return Json(data); } } } |
为了这种简洁的代码我们需要:
1、Controller基类BaseController:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; using System.Data.Entity; using System.Data.SqlClient; using System.Data.Entity.Validation; using System.ComponentModel; using System.Reflection; using System.Web.Security; using formula; namespace formula { public abstract class BaseController : Controller { #region 处理不存在的Action protected override void HandleUnknownAction( string actionName) { if (Request.HttpMethod == "POST" ) { HttpContext.ClearError(); HttpContext.Response.Clear(); HttpContext.Response.StatusCode = 500; HttpContext.Response.Write( "没有Action:" + actionName); HttpContext.Response.End(); } // 搜索文件是否存在 var filePath = "" ; if (RouteData.DataTokens[ "area" ] != null ) filePath = string .Format( "~/Areas/{2}/Views/{1}/{0}.cshtml" , actionName, RouteData.Values[ "controller" ], RouteData.DataTokens[ "area" ]); else filePath = string .Format( "~/Views/{1}/{0}.cshtml" , actionName, RouteData.Values[ "controller" ]); if (System.IO.File.Exists(Server.MapPath(filePath))) { View(filePath).ExecuteResult(ControllerContext); } else { HttpContext.ClearError(); HttpContext.Response.Clear(); HttpContext.Response.StatusCode = 500; HttpContext.Response.Write( "没有Action:" + actionName); HttpContext.Response.End(); } } #endregion #region 基类Json方法重载 protected override JsonResult Json( object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) { NewtonJsonResult result = new NewtonJsonResult() { Data = data, ContentType = contentType, ContentEncoding = contentEncoding, JsonRequestBehavior = behavior }; return result; } protected override JsonResult Json( object data, string contentType, Encoding contentEncoding) { NewtonJsonResult result = new NewtonJsonResult() { Data = data, ContentType = contentType, ContentEncoding = contentEncoding }; return result; } #endregion #region 异常处理 protected override void OnException(ExceptionContext filterContext) { Exception exp = filterContext.Exception; if ( string .IsNullOrEmpty(exp.Message)) exp = exp.GetBaseException(); if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest()) { var response = filterContext.RequestContext.HttpContext.Response; response.Clear(); response.Write(exp.Message); response.StatusCode = 500; response.End(); } } #endregion } } |
2、查询构造器QueryBuilder:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; using System.Web.Mvc; namespace formula { [ModelBinder( typeof (QueryBuilderBinder))] public class QueryBuilder : SearchCondition { public int page { get ; set ; } public int rows { get ; set ; } public string sort { get ; set ; } public string order { get ; set ; } public int total { get ; set ; } public string getOrderByString( bool hasOrderBy = true ) { var sortFields = this .sort.Split( ',' ); var sortOrders = this .order.Split( ',' ); string str = "" ; for ( int i = 0; i < sortFields.Length; i++) { str += sortFields[i] + " " + sortOrders[i] + "," ; } if (hasOrderBy && str != "" ) str = "order by " + str; return str.Trim( ',' ); } } public class SearchCondition { public string fields = "*" ; private List<ConditionItem> quickItems = new List<ConditionItem>(); private List<ConditionItem> complexItems = new List<ConditionItem>(); public SearchCondition add( string field, string method, object val, bool isQuickSearch = false ) { //处理日期型数据 if (method == "<" || method == "<=" ) { if (val.GetType() == typeof (DateTime)) { DateTime t = (DateTime)val; val = t.Date.AddHours(23).AddMinutes(59).AddSeconds(59); } } ConditionItem item = new ConditionItem(field, method, val); if (isQuickSearch) quickItems.Add(item); else complexItems.Add(item); return this ; } public string getWhereString( bool hasWhere = true ) { if (quickItems.Count == 0 && complexItems.Count == 0) return "" ; string strWhere = "" ; if (quickItems.Count > 0) strWhere += " and (" + getGourpWhereString(quickItems, true ) + ")" ; if (complexItems.Count > 0) strWhere += " and (" + getGourpWhereString(complexItems, false ) + ")" ; if (hasWhere) strWhere = " where " + strWhere.Substring(4); else strWhere = " and " + strWhere.Substring(4); return strWhere; } #region 私有方法 private string getGourpWhereString(List<ConditionItem> list, bool isOrRelation = false ) { if (list.Count == 0) return "" ; string strWhere = "" ; for ( int i = 0; i < list.Count(); i++) { var item = list[i]; string str = item.getWhereString(); if (isOrRelation) { strWhere += " or " + str; } else { strWhere += " and " + str; } } strWhere = strWhere.Substring(4); return strWhere; } #endregion } public class ConditionItem { public ConditionItem( string field, string method, object val) { this .field = field; this .method = method; this .value = val; } public string field { get ; set ; } public string method { get ; set ; } public object value { get ; set ; } public string getWhereString() { var item = this ; switch (item.method) { case "=" : case "<" : case ">" : case "<=" : case ">=" : case "<>" : return string .Format( "{0} {1} '{2}'" , item.field, item.method, item.value); case "in" : string v = "" ; if (item.value is ICollection) { ICollection< string > collection = item.value as ICollection< string >; v = string .Join( "','" , collection.ToArray< string >()); return string .Format( "{0} in('{1}')" , item.field, v); } else { v = item.value.ToString().Replace( "," , "','" ); } return string .Format( "{0} in ('{1}')" , item.field, v); case "between" : object [] objs = item.value as object []; return string .Format( "{0} between '{1}' and '{2}'" , item.field, objs[0], objs[1]); case "inLike" : string [] arr = null ; if (item.value is ICollection) { ICollection< string > collection = item.value as ICollection< string >; arr = collection.ToArray< string >(); } else { arr = item.value.ToString().Split( ',' , ',' ); } string str = "" ; foreach ( string s in arr) { str += string .Format( "or {0} like '%{1}%'" , item.field, s); } return "(" + str.Substring(3) + ")" ; case "day" : DateTime dt = DateTime.Now; if (!DateTime.TryParse(item.value.ToString(), out dt)) { throw new BuessinessException( "查询条件不能转化为日期时间" ); } string start = dt.Date.ToString( "yyyy-MM-dd" ); string end = dt.Date.AddDays(1).ToString( "yyyy-MM-dd" ); return string .Format( "{0} between '{1}' and '{2}'" , item.field, start, end); case "startWith" : return string .Format( "{0} like '{1}%'" , item.field, item.value); case "endWith" : return string .Format( "{0} like '%{1}'" , item.field, item.value); default : return "" ; } } } } |
3、查询构造器QueryBuilder的创建方法QueryBuilderBinder:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; namespace formula { public class QueryBuilderBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var qb = (QueryBuilder)(bindingContext.Model ?? new QueryBuilder()); var dict = controllerContext.HttpContext.Request.Params; var quickQueryList = ! string .IsNullOrEmpty(dict[ "quickQueryData" ]) ? JsonHelper.ToList(dict[ "quickQueryData" ]) : new List<Dictionary< string , object >>(); var queryList = ! string .IsNullOrEmpty(dict[ "queryData" ]) ? JsonHelper.ToList(dict[ "queryData" ]) : new List<Dictionary< string , object >>(); foreach (var dic in quickQueryList) { var val = dic[ "value" ].ToString(); if (val == "" ) continue ; qb.add(dic[ "field" ].ToString(), dic[ "method" ].ToString(), val, true ); } foreach (var dic in queryList) { var val = dic[ "value" ].ToString(); if (val == "" ) continue ; qb.add(dic[ "field" ].ToString(), dic[ "method" ].ToString(), val, false ); } qb.page = ! string .IsNullOrEmpty(dict[ "page" ]) ? int .Parse(dict[ "page" ].ToString()) : 1; qb.rows = ! string .IsNullOrEmpty(dict[ "rows" ]) ? int .Parse(dict[ "rows" ].ToString()) : 10; qb.sort = ! string .IsNullOrEmpty(dict[ "sort" ]) ? dict[ "page" ].ToString() : "id" ; qb.order = ! string .IsNullOrEmpty(dict[ "order" ]) ? dict[ "order" ].ToString() : "desc" ; return qb; } } } |
4、数据库查询帮助类SqlHelper:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.SqlClient; using System.Data; using System.Web; namespace formula { public class SqlHelper { #region 构造函数 public SqlHelper( string connName) { if (System.Configuration.ConfigurationManager.ConnectionStrings[connName] == null ) throw new BuessinessException( string .Format( "配置文件中不包含数据库连接字符串:{0}" , connName)); this .connName = connName; this .connString = System.Configuration.ConfigurationManager.ConnectionStrings[connName].ConnectionString; } public string connName { get ; private set ; } public string connString { get ; private set ; } public string dbName { get { SqlConnection conn = new SqlConnection(connString); return conn.Database; } } #endregion #region 基本方法 public object ExecuteScalar( string cmdText) { using (SqlConnection conn = new SqlConnection(connString)) { conn.Open(); SqlCommand cmd = new SqlCommand(cmdText, conn); return cmd.ExecuteScalar(); } } public DataTable ExecuteDataTable( string cmdText) { using (SqlConnection conn = new SqlConnection(connString)) { DataTable dt = new DataTable(); SqlDataAdapter apt = new SqlDataAdapter(cmdText, conn); apt.Fill(dt); return dt; } } public DataTable ExecuteDataTable( string cmdText, int start, int len) { using (SqlConnection conn = new SqlConnection(connString)) { DataTable dt = new DataTable(); SqlDataAdapter apt = new SqlDataAdapter(cmdText, conn); apt.Fill(start, len, dt); return dt; } } public string ExecuteNonQuery( string cmdText) { using (SqlConnection conn = new SqlConnection(connString)) { conn.Open(); SqlCommand cmd = new SqlCommand(cmdText, conn); return cmd.ExecuteNonQuery().ToString(); } } #endregion #region 支持查询对象 public DataTable ExecuteDataTable( string sql, SearchCondition cnd, string orderBy) { string sqlWhere = " where 1=1" + GetUrlFilterSqlWhere(sql) + cnd.getWhereString( false ); sql = string .Format( "select {0} from ({1}) sourceTable {2} {3}" , cnd.fields, sql, sqlWhere, orderBy); DataTable dt = this .ExecuteDataTable(sql); return dt; } public Dictionary< string , object > ExecuteGridData( string sql, QueryBuilder qb) { string sqlWhere = " where 1=1" + GetUrlFilterSqlWhere(sql) + qb.getWhereString( false ); qb.total = ( int ) this .ExecuteScalar( string .Format( "select count(1) from ({0}) sourceTable {1}" , sql, sqlWhere)); sql = string .Format( "select {0} from ({1}) sourceTable {2} {3}" , qb.fields, sql, sqlWhere, qb.getOrderByString()); DataTable dt = ExecuteDataTable(sql, (qb.page - 1) * qb.rows, qb.rows); Dictionary< string , object > dic = new Dictionary< string , object >(); dic.Add( "total" , qb.total); dic.Add( "rows" , dt); return dic; } #endregion #region 私有方法 private string GetUrlFilterSqlWhere( string sql) { sql = string .Format( "select * from({0}) as dt1 where 1=2" , sql); var dtField = ExecuteDataTable(sql); StringBuilder sb = new StringBuilder(); foreach ( string key in HttpContext.Current.Request.QueryString.Keys) { if ( string .IsNullOrEmpty(key) || key.ToLower() == "id" ) continue ; if (dtField.Columns.Contains(key)) { string value = HttpContext.Current.Server.UrlDecode(HttpContext.Current.Request[key]); value = value.Replace( "," , "','" ); sb.AppendFormat( " and {0} in ('{1}')" , key, value); } } return sb.ToString(); } #endregion } } |
5、用于取代返回值JsonResult的NewtonJsonResult:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; using System.Web; using System.Data; namespace formula { public class NewtonJsonResult : JsonResult { public override void ExecuteResult(ControllerContext context) { //确认是否用于响应HTTP-Get请求 if ( this .JsonRequestBehavior == JsonRequestBehavior.DenyGet && string .Compare(context.HttpContext.Request.HttpMethod, "GET" , true ) == 0) { throw new InvalidOperationException( "禁止Get请求" ); } HttpResponseBase response = context.HttpContext.Response; //设置媒体类型和编码方式 response.ContentType = string .IsNullOrEmpty( this .ContentType) ? "application/json" : this .ContentType; if ( this .ContentEncoding != null ) { response.ContentEncoding = this .ContentEncoding; } //序列化对象,并写入当前的HttpResponse if ( null == this .Data) return ; if ( this .Data is string ) { response.Write(Data); } else if ( this .Data is DataRow) { Dictionary< string , object > dic = new Dictionary< string , object >(); DataRow row = this .Data as DataRow; foreach (DataColumn col in row.Table.Columns) { dic.Add(col.ColumnName, row[col]); } response.Write(JsonHelper.ToJson(dic)); } else { response.Write(JsonHelper.ToJson( this .Data)); } } } } |
6、Json序列化和反序列的帮助类JsonHelper:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Newtonsoft.Json.Converters; using Newtonsoft.Json; namespace formula { public static class JsonHelper { public static string ToJson<T>(T obj) { if (obj == null || obj.ToString() == "null" ) return null ; if (obj != null && (obj.GetType() == typeof (String) || obj.GetType() == typeof ( string ))) { return obj.ToString(); } IsoDateTimeConverter dt = new IsoDateTimeConverter(); dt.DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss" ; return JsonConvert.SerializeObject(obj, dt); } /// <summary> /// 从一个Json串生成对象信息 /// </summary> /// <param name="jsonString">JSON字符串</param> /// <typeparam name="T">对象类型</typeparam> /// <returns></returns> public static T ToObject<T>( string json) where T : class { if (String.IsNullOrEmpty(json)) return null ; T obj = JsonConvert.DeserializeObject<T>(json); return obj; } /// <summary> /// 返回 Diction<string,object> /// </summary> /// <param name="json"></param> /// <returns></returns> public static Dictionary< string , object > ToObject( string json) { if (String.IsNullOrEmpty(json)) return new Dictionary< string , object >(); return ToObject<Dictionary< string , object >>(json); } /// <summary> /// 返回 List<Dictionary<string, object>> /// </summary> /// <param name="json"></param> /// <returns></returns> public static List<Dictionary< string , object >> ToList( string json) { if (String.IsNullOrEmpty(json)) return new List<Dictionary< string , object >>(); return ToObject<List<Dictionary< string , object >>>(json); } /// <summary> /// 组装对象 /// </summary> /// <param name="json"></param> /// <param name="obj"></param> public static void PopulateObject( string json, object obj) { if (String.IsNullOrEmpty(json)) return ; JsonConvert.PopulateObject(json, obj); } } } |
7、用于区分系统异常和业务异常的BusinessException:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.Serialization; namespace formula { /// <summary> /// 业务异常 /// </summary> [Serializable] public class BuessinessException : Exception { /// <summary> /// 系统异常构造函数 /// </summary> public BuessinessException() { } /// <summary> /// 系统异常构造函数 /// </summary> /// <param name="message">异常的消息</param> public BuessinessException( string message) : base (message) { } /// <summary> /// 系统异常构造函数 /// </summary> /// <param name="message">异常的消息</param> /// <param name="inner">内部的异常</param> public BuessinessException( string message, System.Exception inner) : base (message, inner) { } /// <summary> /// 系统异常构造函数 /// </summary> /// <param name="info">存有有关所引发异常的序列化的对象数据</param> /// <param name="context">包含有关源或目标的上下文信息</param> public BuessinessException(SerializationInfo info, StreamingContext context) : base (info, context) { } } } |
最后,上代码:29.rar