ASP.NET WEBAPI 简单CURD综合测试(asp.net MVC,json.net,sql基础存储过程和视图,sqlhelper,json解析)
草图

真正的后端是不管前端是什么平台,用什么语言的,JSON格式的数据应该可以应对。用ASP.NET WEBAPI尝试做一个后端,实现最基本的CURD,业务逻辑和数据库操作都放在后端,前端只需要正确访问和提供必要的数据就行。
个人习惯
我喜欢先意淫一下需求,然后找出需要的实体和逻辑,而不是先设计数据库,现在EF那么牛逼,完全可以在代码上生成表和表之间的关系,各种查询语句效率并不一定比你写sql语句差。所以我在做东西的时候从来不先考虑数据的。但是今天主要是练习api和复习一下ado.net的CURD,所以没有用EF。长时间用EF不写sql,都忘光了啊。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Model { public class Employee { public int Id { get; set; } public int Age { get; set; } public string Number { get; set; } public string Name { get; set; } public int DepartmentId { get; set; } public string Gender { get; set; } public string Job { get; set; } public string Telephone { get; set; } public float Salary { get; set; } public DateTime EntryTime { get; set; } } }
Employee
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Model { public class Department { public int Id { get; set; } public string Number { get; set; } public string Name { get; set; } public string Manager { get; set; } public bool IsDel { get; set; } } }
Department
using System.Data; using System.Data.SqlClient; using System.Collections; using System; using System.Configuration; namespace DAL { public abstract class SqlHelper { /// <summary> /// 数据库连接字符串 /// </summary> public static readonly string connectionString = ConfigurationManager.ConnectionStrings["conStr"].ToString(); // 线程安全的哈希表 private static Hashtable parmCache = Hashtable.Synchronized(new Hashtable()); /// <summary> /// 为执行命令准备参数 /// </summary> /// <param name="cmd">SqlCommand 命令</param> /// <param name="conn">已经存在的数据库连接</param> /// <param name="cmdType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param> /// <param name="cmdText">Command text,T-SQL语句 例如 Select * from Products</param> /// <param name="cmdParms">返回带参数的命令</param> private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, CommandType cmdType, string cmdText, SqlParameter[] cmdParms) { if (conn.State != ConnectionState.Open) conn.Open(); cmd.Connection = conn; cmd.CommandType = cmdType; if (cmdParms != null) cmd.Parameters.AddRange(cmdParms); cmd.CommandText = cmdText; } public static int NonQuery(CommandType type,string sql,params SqlParameter[]pars) { SqlCommand cmd = new SqlCommand(); using (SqlConnection con = new SqlConnection(connectionString)) { PrepareCommand(cmd, con, type, sql, pars); int n = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); return n; } } /// <summary> /// Execute a SqlCommand that returns a resultset against the database /// </summary> /// <param name="connectionString">一个有效的数据库连接字符串</param> /// <param name="cmdType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param> /// <param name="cmdText">存储过程的名字或者 T-SQL 语句</param> /// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param> /// <returns>一个SqlDataReader的结果</returns> public static SqlDataReader ExecuteReader(CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) { SqlCommand cmd = new SqlCommand(); SqlConnection conn = new SqlConnection(connectionString); try { PrepareCommand(cmd, conn,cmdType, cmdText, commandParameters); SqlDataReader sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection); cmd.Parameters.Clear(); return sdr; } catch { conn.Close(); throw; } } public static DataSet GetDataSet(CommandType type,string sql,params SqlParameter[]pars) { SqlCommand cmd = new SqlCommand(); DataSet ds = new DataSet(); using (SqlConnection con = new SqlConnection(connectionString)) { PrepareCommand(cmd, con, type, sql, pars); using (SqlDataAdapter adp = new SqlDataAdapter(cmd)) { adp.Fill(ds); //cmd.Parameters.Clear(); } } return ds; } #region ExecuteScalar方法 /// <summary> /// 返回第一行的第一列 /// </summary> /// <param name="cmdType">SqlCommand命令类型 (存储过程, T-SQL语句, 等等。)</param> /// <param name="cmdText">存储过程的名字或者 T-SQL 语句</param> /// <param name="commandParameters">以数组形式提供SqlCommand命令中用到的参数列表</param> /// <returns>返回一个对象</returns> public static object Scalar(CommandType type, string sql, params SqlParameter[] pars) { SqlCommand cmd = new SqlCommand(); using (SqlConnection con = new SqlConnection(connectionString)) { PrepareCommand(cmd, con, type, sql, pars); object o = cmd.ExecuteScalar(); cmd.Parameters.Clear(); return o; } } #endregion /// <summary> /// 缓存参数 /// </summary> /// <param name="cacheKey">索引键</param> /// <param name="cmdParms">参数数组</param> public static void CacheParameters(string cacheKey, params SqlParameter[] commandParameters) { parmCache[cacheKey] = commandParameters; } /// <summary> /// 通过索引键获取哈希表中的sql参数 /// </summary> /// <param name="cacheKey"></param> /// <returns></returns> public static SqlParameter[] GetCachedParameters(string cacheKey) { SqlParameter[] cachedParms = (SqlParameter[])parmCache[cacheKey]; if (cachedParms == null) return null; SqlParameter[] clonedParms = new SqlParameter[cachedParms.Length]; , j = cachedParms.Length; i < j; i++) clonedParms[i] = (SqlParameter)((ICloneable)cachedParms[i]).Clone(); return clonedParms; } /// <summary> /// 检查是否存在 /// </summary> /// <param name="strSql">Sql语句</param> /// <returns>bool结果</returns> public static bool Exists(string strSql) { int cmdresult = Convert.ToInt32(Scalar(CommandType.Text, strSql, null)); ) { return false; } else { return true; } } /// <summary> /// 检查是否存在 /// </summary> /// <param name="strSql">Sql语句</param> /// <param name="cmdParms">参数</param> /// <returns>bool结果</returns> public static bool Exists(string strSql, params SqlParameter[] cmdParms) { int cmdresult = Convert.ToInt32(Scalar(CommandType.Text, strSql, cmdParms)); ) { return false; } else { return true; } } } }
SqlHelper
有一个常用的视图
USE [Demo] GO /****** Object: View [dbo].[EmpView] Script Date: 2016/8/22 16:06:46 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO create view [dbo].[EmpView] as select Employee.Number as 编号, Employee.Name as 姓名, Department.Name as 部门, Employee.Age as 年龄, Employee.Gender as 性别, Employee.Job as 职位, Employee.Telephone as 电话, Employee.Salary as 工资, Employee.EntryTime as 入职时间 from Employee ,Department where Department.Id=Employee.DepartmentId GO
EmpView
开始意淫
分页查询所有的员工信息,以前面的视图为模型。写一个简单的,没有过滤的分页存储过程
USE [Demo] GO /****** Object: StoredProcedure [dbo].[Pager] Script Date: 2016/8/22 16:26:03 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE procedure [dbo].[Pager] @index int ,@size int,@count int output as begin declare @c int )*@size select @c=count(*) from EmpView set @count=@c end
Pager
准备把所有的业务放在API项目中
using Model; using System; using System.Collections.Generic; using System.Linq; using System.Web; using DAL; using System.Data; using Newtonsoft.Json; using Newtonsoft; using System.Data.SqlClient; namespace WebApiTest { public class BLL { private dynamic GetLineEmpView(DataRow row) { return new { Age = row["年龄"] == DBNull.Value ? string.Empty : row["年龄"].ToString(), Salary = row["工资"] == DBNull.Value ? string.Empty : row["工资"].ToString(), Name = row["姓名"] == DBNull.Value ? string.Empty : row["姓名"].ToString(), Job = row["职位"] == DBNull.Value ? string.Empty : row["职位"].ToString(), Number = row["编号"] == DBNull.Value ? string.Empty : row["编号"].ToString(), Telephone = row["电话"] == DBNull.Value ? string.Empty : row["电话"].ToString(), Gender = row["性别"] == DBNull.Value ? string.Empty : row["性别"].ToString(), EntryTime = row["入职时间"] == DBNull.Value ? string.Empty :row["入职时间"].ToString(), DepName = row["部门"].ToString() }; } public List<dynamic> GetEmpView() { List<dynamic> list = new List<dynamic>(); string sql = "select * from EmpView"; DataTable dt = SqlHelper.GetDataSet(CommandType.Text, sql, ]; if(dt!=null) { foreach (DataRow row in dt.Rows) list.Add(GetLineEmpView(row)); return list; } return list; } public List<dynamic> GetEmpView(int index,int size,out int count) { string sql = "Pager"; SqlParameter[] pars = { new SqlParameter("@index",SqlDbType.Int), new SqlParameter("@size",SqlDbType.Int), new SqlParameter("@count",SqlDbType.Int) }; pars[].Value = index; pars[].Direction = ParameterDirection.Input; pars[].Value = size; pars[].Direction = ParameterDirection.Input; pars[].Direction = ParameterDirection.Output; DataTable dt = SqlHelper.GetDataSet(CommandType.StoredProcedure, sql, pars).Tables[]; ].Value.ToString(), out count); List<dynamic> list = new List<dynamic>(); if(dt!=null) { foreach (DataRow row in dt.Rows) list.Add(GetLineEmpView(row)); } return list; } } }
BLL
apicontroller调用这个这个类,对外提供2个GET的restful响应api,返回json格式的数据。这里的JSON数据没有处理好,用的.net的JsonResult格式,而不是直接用json.net返回,原因是直拉用json.net返回的时候,把原本排好的json格式又加了“”号和转义\。这个以后再想办法,现在也只是多了几个.net默认的几条数据,不要它就行了。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Http; using System.Web.Mvc; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace WebApiTest.Controllers { public class CompanyController : ApiController { private BLL bll = new BLL(); public JsonResult Get() { return new JsonResult { Data = bll.GetEmpView() }; } public JsonResult Get(int pageIndex,int pageSize) { int count; string data=JsonConvert.SerializeObject( bll.GetEmpView(pageIndex, pageSize, out count)); var json=new JObject(new JProperty("PageTotalCount", count), new JProperty("EmpList", data)); return new JsonResult { Data = json }; } } }
CompanyController
哈哈哈哈,说好的CURD可是从早上到现在只完成一个简单的分页查询,不过我觉得把这个做好了,其它的只是照搬了。那么对于这个简单需求来说,后端的工作已经完成了。再就是前端调用展示了。
前端调用和展示
客户端暂时封装一个对服务的GET请求
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Web; namespace TestMVCApp { public class RestClient { private string BaseUri; public RestClient(string baseUri) { this.BaseUri = baseUri; } public string Get(string uri) { //Web访问服务 string serviceUrl = string.Format("{0}/{1}", this.BaseUri, uri); //构造一个Web请求的对象 HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(serviceUrl); //获取web请求的响应的内容 HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse(); //通过响应流构造一个StreamReader StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8); //string ReturnXml = HttpUtility.UrlDecode(reader.ReadToEnd()); string ReturnXml = reader.ReadToEnd(); reader.Close(); myResponse.Close(); return ReturnXml; } } }
RestClient
虽然我是在一个解决方案里做的,但我假设前端对后端一无所知,只知道自己需要什么,后端能给什么。所以另外搞个视图的模型类,接收数据(Models文件夹中)
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace TestMVCApp.Models { public class EmpView { public string Name { get; set; } public string Age { get; set; } public string DepName { get; set; } public string Salary { get; set; } public string Job { get; set; } public string Number { get; set; } public string Telephone { get; set; } public string Gender { get; set; } public string EntryTime { get; set; } } public class EmpData { public int PageTotalCount { get; set; } public List<EmpView> EmpList { get; set; } } }
TestMVCApp.Models
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using TestMVCApp.Models; namespace TestMVCApp.Controllers { public class HomeController : Controller { private RestClient client = new RestClient("http://localhost:2154/"); // GET: Home public ActionResult Index() { string uriGet = "api/Company?pageIndex=1&pageSize=5"; string json = JObject.Parse(client.Get(uriGet))["Data"].ToString(); string count = JObject.Parse(json)["PageTotalCount"].ToString(); string emp = JObject.Parse(json)["EmpList"].ToString(); List<EmpView> empList = JsonConvert.DeserializeObject<List<EmpView>>(emp); EmpData ed = new EmpData(); ed.PageTotalCount = int.Parse(count); ed.EmpList = empList; return View(ed); } } }
TestMVCApp.Controllers
@{ Layout = null; } @model TestMVCApp.Models.EmpData <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <link href="~/Content/bootstrap.min.css" rel="stylesheet" /> <script src="~/Scripts/jquery-1.9.1.min.js"></script> <script src="~/Scripts/bootstrap.min.js"></script> <title>Index</title> <script type="text/javascript"> $(function () { $("#btn").click(function () { $.get("http://localhost:2154/api/conpany?pageIndex=" + $("#pageIndex").val() + "&pageSize=" + $("#pageSize").val(), {}, function (data) { $("#empBody tr").remove(); var json = data.Data var empList = $.parseJSON(json.EmpList) $.each(empList, function (i, item) { $("#empBody").append("<tr><td>" +item.Name+"</td><td>" + item.Number + "</td><td>" + item.DepName + "</td><td>" + item.Gender + "</td><td>" + item.Age + "</td><td>" + item.Telephone + "</td><td>" + item.Salary + "</td><td>" + item.Job + "</td><td>" +item.EntryTime+ "</td></tr>") }) }) }) }) </script> </head> <body> <div> <table id="empList" class="table"> <thead> <tr> <td>姓名</td> <td>编号</td> <td>部门</td> <td>性别</td> <td>年龄</td> <td>电话</td> <td>工资</td> <td>职位</td> <td>入职时间</td> </tr> </thead> <tbody id="empBody"> @foreach(var item in Model.EmpList) { <tr> <td> @item.Name</td> <td> @item.Number</td> <td> @item.DepName</td> <td> @item.Gender</td> <td> @item.Age</td> <td> @item.Telephone</td> <td> @item.Salary</td> <td> @item.Job</td> <td> @item.EntryTime</td> </tr> } </tbody> </table> <input id="pageIndex" type="text" /><input type="text" id="pageSize" /> <button id="btn">GO</button> </div> </body> </html>
View
用控制台也测试了一下的
namespace TestConsoleApp { class Program { static void Main(string[] args) { RestClient client = new RestClient("http://localhost:2154/"); string uriGet = "api/Company?pageIndex=1&pageSize=6"; JObject data =(JObject)JObject.Parse( client.Get(uriGet))["Data"]; string ed = data.ToString(); string count = data["PageTotalCount"].ToString(); List<EmpView> list = JsonConvert.DeserializeObject<List<EmpView>>(data["EmpList"].ToString()); Console.WriteLine(count); Console.WriteLine(list.Count); Console.WriteLine(ed); Console.ReadKey(); } } }
TestConsoleApp
其实那个MVC要不要都行,对于这个简单的需求来说,完全可以一个html页面用JQ的异步请求页就可以完成。我靠,几乎全部都没写注释,过段时间估计我自己都理解不了的。看来写注释是很有必要的啊。ASP.NET WEBAPI相对WCF来说还是简单多了,对于简单的应用完全可取代MVC的控制器了嘛,感觉用WEBAPI加JS(JQ)才是真正的MVC啊
ASP.NET WEBAPI 简单CURD综合测试(asp.net MVC,json.net,sql基础存储过程和视图,sqlhelper,json解析)的更多相关文章
- ASP.NET WebApi 简单记录
//获取当前提交过来的Request对象 var request = System.Web.HttpContext.Current.Request;
- 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) ASP.NET WebApi技术从入门到实战演练 C#面向服务WebService从入门到精通 DataTable与List<T>相互转换
路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一位程序猿,在他MVC程序中, ...
- 细说Asp.Net WebAPI消息处理管道
我们在开发完Asp.Net WebAPI程序后,可以使用WebHost寄宿方式或者SelfHost寄宿方式来部署Asp.Net WebAPI.所谓WebHost寄宿就是通过Asp.Net来实现:所谓S ...
- Asp.Net WebApi+Microsoft.AspNet.WebApi.Core 启用CORS跨域访问
WebApi中启用CORS跨域访问 1.安装 Nugget包Microsoft.AspNet.WebApi.Cors This package contains the components to e ...
- ASP.NET WebApi技术从入门到实战演练
一.课程介绍 曾经有一位不知名的讲师说过这么一句名言: 一门RPC技术不会,那么千万万门RPC技术将都不会!在今天移动互联网的时代,作为攻城师的我们,谁不想着只写一套API就可以让我们的Web, An ...
- Asp.Net WebAPI及相关技术介绍(含PPT下载)
此PPT讲述了Asp.Net WebAPI及相关Web服务技术发展历史. 共80多页,Asp.Net WebAPI在讲到第36页的时候才会出现,因为这个技术不是凭空产生的,它有着自己的演变进化的历史. ...
- abp(net core)+easyui+efcore实现仓储管理系统——使用 WEBAPI实现CURD (十三)
abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ...
- 使用ASP.Net WebAPI构建REST服务(一)——简单的示例
由于给予REST的Web服务非常简单易用,它越来越成为企业后端服务集成的首选方法.本文这里介绍一下如何通过微软的Asp.Net WebAPI快速构建REST-ful 服务. 首先创建一个Asp.Net ...
- Asp.Net WebApi核心对象解析(下篇)
在接着写Asp.Net WebApi核心对象解析(下篇)之前,还是一如既往的扯扯淡,元旦刚过,整个人还是处于晕的状态,一大早就来处理系统BUG,简直是坑爹(好在没让我元旦赶过来该BUG),队友挖的坑, ...
随机推荐
- Window.document对象 轮播练习
Window.document对象 一.找到元素: docunment.getElementById("id"):根据id找,最多找一个: var a =docun ...
- Java 多继承
浅浅地上了几天 Java 的课程,然后怎么也想不明白:Java 不支持多继承有和接口到底是什么样的关系? 一只牛的故事. // 叫的抽象基类 abstract class call{ } // 跑的抽 ...
- 解决jsp中文乱码问题
1. 先解决响应中的乱码 何为响应中的乱码?把页面中的"username"改成"用户名"你就知道了. 所谓响应中的乱码,就是显示页面上的乱码,因为页面数据是从服 ...
- vbox下Oracle Enterprise liunx5.4虚拟机安装10G RAC实验(四)
接第3篇 http://www.cnblogs.com/myrunning/p/4003527.html 5.安装配置数据库 5.1安装数据库软件 5.2配置监听 5.3创建ASM磁盘 5.4创建服务 ...
- cocos2d-x渲染流程
Cocos2Dx之渲染流程 发表于8个月前(2014-08-08 22:46) 阅读(3762) | 评论(2) 17人收藏此文章, 我要收藏 赞2 如何快速提高你的薪资?-实力拍“跳槽吧兄弟”梦 ...
- js去除中间空格
/ 功能: 1)去除字符串前后所有空格 // 2)去除字符串中所有空格(包括中间空格,需要设置第2个参数为:g) function Trim(str,is_global) { var result; ...
- 【iCore3 双核心板】例程一:ARM驱动三色LED
实验指导书及代码包下载: http://pan.baidu.com/s/1o6w6Xnk iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...
- 【iCore3 双核心板_ uC/OS-III】例程六:信号量——共享资源
实验指导书及代码包下载: http://pan.baidu.com/s/1milKoVA iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...
- mysql5.5手册读书日记(2)
<?php /* * * MySQL_5.5中文参考手册 485开始 * * mysql> SELECT CASE 1 WHEN 1 THEN 'one' -> WHEN 2 THE ...
- asp.net identity 2.2.0 中角色启用和基本使用(六)
创建用户管理相关视图 第一步:添加视图 打开UsersAdminController.cs 将鼠标移动到public ActionResult Index()上 右键>添加视图 系 ...