一步一步搭框架(asp.netmvc+easyui+sqlserver)-03
一步一步搭框架(asp.netmvc+easyui+sqlserver)-03
我们期望简洁的后台代码,如下:
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:
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 = ;
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 = ;
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 = ;
response.End();
}
} #endregion
} }
2、查询构造器QueryBuilder:
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 = ; 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().AddMinutes().AddSeconds();
}
} 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 == && complexItems.Count == )
return ""; string strWhere = ""; if (quickItems.Count > )
strWhere += " and (" + getGourpWhereString(quickItems, true) + ")";
if (complexItems.Count > )
strWhere += " and (" + getGourpWhereString(complexItems, false) + ")"; if (hasWhere)
strWhere = " where " + strWhere.Substring();
else
strWhere = " and " + strWhere.Substring(); return strWhere;
} #region 私有方法 private string getGourpWhereString(List<ConditionItem> list, bool isOrRelation = false)
{ if (list.Count == )
return ""; string strWhere = "";
for (int i = ; i < list.Count(); i++)
{
var item = list[i];
string str = item.getWhereString(); if (isOrRelation)
{
strWhere += " or " + str;
}
else
{
strWhere += " and " + str;
}
} strWhere = strWhere.Substring(); 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[], objs[]);
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() + ")";
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().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:
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()) : ;
qb.rows = !string.IsNullOrEmpty(dict["rows"]) ? int.Parse(dict["rows"].ToString()) : ;
qb.sort = !string.IsNullOrEmpty(dict["sort"]) ? dict["page"].ToString() : "id";
qb.order = !string.IsNullOrEmpty(dict["order"]) ? dict["order"].ToString() : "desc"; return qb; }
}
}
4、数据库查询帮助类SqlHelper:
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 - ) * 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:
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) == )
{
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:
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:
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)
{ }
}
}
以上为目前的全部代码。
一步一步搭框架(asp.netmvc+easyui+sqlserver)-03的更多相关文章
- 一步一步搭框架(asp.netmvc+easyui+sqlserver)-02
一步一步搭框架(asp.netmvc+easyui+sqlserver)-02 我们期望简洁带前台代码,如下: <table id="dataGrid" class=&quo ...
- 一步一步搭框架(asp.netmvc+easyui+sqlserver)-01
一步一步搭框架(asp.netmvc+easyui+sqlserver)-01 要搭建的框架是企业级开发框架,适用用企业管理信息系统的开发,如:OA.HR等 1.框架名称:sampleFrame. 2 ...
- (转) 一步一步学习ASP.NET 5 (四)- ASP.NET MVC 6四大特性
转发:微软MVP 卢建晖 的文章,希望对大家有帮助.原文:http://blog.csdn.net/kinfey/article/details/44459625 编者语 : 昨晚写好的文章居然csd ...
- ASP.NET MVC 3 Model【通过一简单实例一步一步的介绍】
今天主要讲Model的两个方面: 1. ASP.Net MVC 3 Model 简介 通过一简单的事例一步一步的介绍 2. ASP.Net MVC 3 Model 的一些验证 MVC 中 Model ...
- 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](一)
前言 大家好,我是Rector 从今天开始,Rector将为大家推出一个关于创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar]的文章系列, ...
- 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](四)
前言 上一篇<一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](三)>,我们完成了: * 引用SqlSugar * ...
- 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](三)
前言 上一篇<一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](二)>我们通过如下操作: 创建实体及工具类 创建Re ...
- #使用abp框架与vue一步一步写我是月老的小工具(2) 后台搭建初体验
#使用abp框架与vue一步一步写我是月老的小工具(2) 后台搭建初体验 一.续上前言 关于这个小玩意的产品思考,假设我暂时把他叫我是月老热心人 这是一个没有中心的关系链,每个人进入以后都是以自己为中 ...
- 3、带你一步一步学习ASP.NET Core中的配置之Configuration
如果你是刚接触ASP.NET Core的学习的话,你会注意到:在ASP.NET Core项目中,看不到.NET Fraemwork时代中的web.config文件和app.config文件了.那么你肯 ...
随机推荐
- 了解真实的『REM』手机屏幕适配
rem 作为一个低调的长度单位,由于手机端网页的兴起,在屏幕适配中得到重用.使用 rem 前端开发者可以很方便的在各种屏幕尺寸下,通过等比缩放的方式达到设计图要求的效果. rem 的官方定义『The ...
- JAV07接口与继承之动手动脑问题解决
动手动脑:请自行编写代码测试以下特性:在子类中,若要调用父类中被覆盖的方法,可以使用super关键字. 1.源代码: package Work; class A{ public A(){ System ...
- VA01复制单据,更新定价日期和价格
用户经常复制单据,而复制单据的时候会带过来很多日期的历史数据.定价日期就是其中之一,而价格经常变动,或者删除的话,会出现价格错误等等情况. 1.更新定价日期,保证不会使用历史价格. 2.更新价格,保证 ...
- django服务器配置
服务器配置是Ubuntu14.04 64位OS ubuntu14.04默认是安装好了python2.7版本不用自己安装了. 先更新下源 sudo apt-get update 第一步先安装pip su ...
- 《Linux内核设计与实现》课本第五章学习笔记——20135203齐岳
<Linux内核设计与实现>课本第五章学习笔记 By20135203齐岳 与内核通信 用户空间进程和硬件设备之间通过系统调用来交互,其主要作用有三个. 为用户空间提供了硬件的抽象接口. 保 ...
- Elasticsearch使用备忘
最近我们需要对大约2T(6.5亿条)日志做全文检索,Elasticsearch看起来很火爆,又有很多产品使用(Facebook.github.stackoverflow),值得一试.以下是一些基础知识 ...
- iOS开发_内存泄漏、内存溢出和野指针之间的区别
今天,在工作群中,被问到了内存泄漏和野指针指向的区别,自己答的不是很好,特意回来查了资料,在博文中总结一下经验,欢迎指正. 内存泄漏:是指在堆区,alloc 或new 创建了一个对象,但是并没有放到自 ...
- 手把手教你使用PS切图
http://blog.csdn.net/jiangwei0910410003/article/details/41627565
- VS2015快捷键
Shift+Alt+Enter: 切换全屏编辑 Ctrl+B,T / Ctrl+K,K: 切换书签开关Ctrl+B,N / Ctrl+K,N: 移动到下一书签Ctrl+B,P: 移动到上一书签Ctrl ...
- widows下node.js环境搭建及运行js
昨天刚刚开始学习node.js,网上一些教程不是很清楚,所以总结一下我的经验. 1.安装. 安装省略,就到官网上去下载安装一下就好.安装完成之后,打开cmd,输入"path",查看 ...