进到这个公司一直就是winform和Silverlight,实在是没有实战web项目的机会。大D也辞职了,去搞web app了。自己也该闲暇时间多学习学习,每天进步一点点。

AD:【线下活动】三大新锐HTML 5企业汇聚51CTO—大话移动前端技术

OK,不多说了,看一下Solution的截图

基本上一看就明白了,控制器调用Biz层,Biz层调用DAL层,DAL层进行数据的CURD。Utility是一些公用的类库。ok,为什么程序集的命名都是以Bruce开头呢,因为我在公司的英文名叫这个。废话不多说,我们先看一下页面

我们引入了BootStrap,主要是为了页面布局。在Views中Partial下面放的都是部分页。

我们先看一下运行效果,今天主要是讲页面初始化部分。

其实查询条件就是婚否,出生日期,姓名的模糊查询。我们先看一下页面Index.cshtml的代码

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width;initial-scale=1" />
  7. <title>Compare data between Solr and DB</title>
  8. <link rel="stylesheet" type="text/css" href="~/BootStrap/css/bootstrap-theme.css" />
  9. <link rel="stylesheet" type="text/css" href="~/BootStrap/css/bootstrap.css" />
  10. @*@Styles.Render("~/css")*@
  11. @Scripts.Render("~/bundles/BootStrap")
  12. @Scripts.Render("~/bundles/Scripts")
  13. <style type="text/css">
  14. .pre-Scrollable {
  15. max-height: 700px;
  16. overflow-y: scroll;
  17. }
  18. </style>
  19. </head>
  20. <body>
  21. <div class="container">
  22. <form id="formsync">
  23. <div class="row">
  24. <div class="col-md-12">
  25. <h1 style="color:red"><b>Compare Data Between Solr and DB</b></h1>
  26. </div>
  27. </div>
  28. <div class="row" id="divloding" style="display:none;text-align:center">
  29. <div class="col-md-6">
  30. <img src="~/Images/ajaxLoading.gif" alt="load failed" />
  31. <label>getting,please wait......</label>
  32. </div>
  33. </div>
  34. <div class="row" id="divcompare" style="display:none;text-align:center">
  35. <div class="col-md-6">
  36. <img src="~/Images/ajaxLoading.gif" alt="load failed" />
  37. <label>comparing,please wait......</label>
  38. </div>
  39. </div>
  40. <div class="row" id="divfix" style="display:none;text-align:center">
  41. <div class="col-md-6">
  42. <img src="~/Images/ajaxLoading.gif" alt="load failed" />
  43. <label>fixing,please wait......</label>
  44. </div>
  45. </div>
  46. <div class="row" style="margin-top:10px">
  47. <div class="col-md-12 form-inline">
  48. <div class="form-group input-group">
  49. <span class="input-group-addon">IsMarried:</span>
  50. @Html.DropDownList("ddlMarried", ViewBag.MarriedList as SelectList, null, new { id = "ddlMarried", @class = "form-control" })
  51. </div>
  52. <div class="form-group" style="margin-left:10px">
  53. <label class="control-label">BirthDay:</label>
  54. <input type="date" id="txtdatestart" class="form-control">
  55. <label class="control-label">-</label>
  56. <input type="date" id="txtdateend" class="form-control">
  57. </div>
  58. <div class="form-group input-group" style="margin-left:10px">
  59. <span class="input-group-addon">Name:</span>
  60. <input id="txtusername" type="text" class="form-control" placeholder="input name..." style="width:120px" />
  61. </div>
  62. <div class="form-group" style="margin-left:10px">
  63. <input id="btnsearch" type="button" class="btn btn-info" value="Get" style="width:70px" />
  64. </div>
  65. </div>
  66. </div>
  67. <div class="row" style="margin-top:10px">
  68. <div id="divresult" class="col-md-7 form-inline  pre-Scrollable">
  69. @{Html.RenderPartial("~/Views/Partial/UserInfoPartial.cshtml");}
  70. </div>
  71. <div class="col-md-5">
  72. @{Html.RenderPartial("~/Views/Partial/DiffAndSameWithSolrPartial.cshtml");}
  73. </div>
  74. </div>
  75. </form>
  76. </div>
  77. </body>
  78. </html>

我们使用html5+BootStrap布局,这里用到了BootStrap的网格系统,将浏览器平分为12份,即12列,很容易构造出响应式布局系统。那么什么是BootStrap的网格系统,看如下的解释

OK,我们怎么看是否是响应式的布局呢,我们打开谷歌浏览器,现将浏览器缩小到一定程度。

看到了吧,即使设备浏览器这么小,我们还是能用。那我们在手机模拟器中测试一下,打开谷歌浏览器,按F12,点击手机模拟器样的东西,然后Device选择iphone6。

我们看到iphone6下面的效果是这样的。说到这里我最近很讨厌两个广告,一个是“这个是iphone6,这个是iphone6 plus,它们都有一个叫健康的东西.....但是好吃啊”,还有一个是“当牛魔王变成一个饺子,我愿意变成一双筷子”。看到这两个广告,我想砸电视。

那为什么不同的设备不同的浏览器都是可以正常浏览的呢,原因就在于这段代码

  1. <meta name="viewport" content="width=device-width;initial-scale=1" />

这段代码的意思是网页宽度默认等于屏幕宽度,缩放比例默认为1(网页初始比例占屏幕的100%)。

ok,我们接下来看head部分css和js的引用,这里有个新东西叫Bundle,用来打包压缩js或者css的。通过它打包压缩的js或者css客户端只需要下载一次包即可,而且可以在客户端缓存起来,当检测到有更新时,才会重新下载。

下面是Bundle.cs的代码

  1. using System.Web;
  2. using System.Web.Optimization;
  3. namespace Brue.GRLC.Web
  4. {
  5. public class BundleConfig
  6. {
  7. // 有关 Bundling 的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkId=254725
  8. public static void RegisterBundles(BundleCollection bundles)
  9. {
  10. bundles.Add(new ScriptBundle("~/bundles/BootStrap").Include(
  11. "~/Scripts/jquery-1.11.1.js","~/BootStrap/js/bootstrap.js"));
  12. bundles.Add(new ScriptBundle("~/bundles/Scripts").Include("~/Js/Index.js"));
  13. bundles.Add(new StyleBundle("~/css").Include("~/BootStrap/css/bootstrap-theme.css"
  14. , "~/BootStrap/css/bootstrap.css"));
  15. }
  16. }
  17. }

注意,在这里引用js的时候不要引用压缩过的js,比如xxx.min.js。当Bundle在遇到这种js命名文件的时候,直接就忽略掉了。那么我们在Head中只需要使用如下代码来引用即可。

  1. @Scripts.Render("~/bundles/BootStrap")
  2. @Scripts.Render("~/bundles/Scripts")

OK,在这我碰到一个问题,就是我的css通过这种方式引用,始终提示Index out of range。如果哪位大牛知道原因的话麻烦留个言,谢谢!

OK,我们接下来看一下控制器代码,页面刚进来,会走Home/Index。

  1. public ActionResult Index()
  2. {
  3. List<object> marriedList = GRLCBiz.GetInstance().GetMarriedList();
  4. SelectList selectList = new SelectList(marriedList, "MarriedID", "DisplayContent", "-1");
  5. ViewBag.MarriedList = selectList;
  6. DataResponse<UserDBEntity> dataResponse = GRLCBiz.GetInstance().GetUserInfoEntityList();
  7. UserInfoViewModel userInfoViewModel = new UserInfoViewModel();
  8. userInfoViewModel.DataResponse = dataResponse;
  9. userInfoViewModel.DataResponse.PageIndex = ConstValues.CONN_DefaultPageIndex;
  10. userInfoViewModel.DataResponse.PageSize = ConstValues.CONN_DefaultPageSize;
  11. userInfoViewModel.DataResponse.StartPageIndex = 1;
  12. return View(userInfoViewModel);
  13. }

首先我们构造了一个SelectList用于下拉列表,Biz层的代码很简单

  1. public dynamic GetMarriedList()
  2. {
  3. IList<object> marriedList = new List<object>();
  4. marriedList.Add(new { MarriedID = -1, DisplayContent = "No Selection" });
  5. marriedList.Add(new { MarriedID = 0, DisplayContent = "Married" });
  6. marriedList.Add(new { MarriedID = 1, DisplayContent = "UnMarried" });
  7. return marriedList;
  8. }

用匿名类去构造一个List。接下来就是DataReponse的获取,Biz层的代码如下

  1. public DataResponse<UserDBEntity> GetUserInfoEntityList(UserInfoRequest request = null)
  2. {
  3. if(request==null)
  4. {
  5. request = new UserInfoRequest();
  6. request.PageIndex = ConstValues.CONN_DefaultPageIndex;
  7. request.PageSize = ConstValues.CONN_DefaultPageSize;
  8. }
  9. int totalCount=0;
  10. List<UserDBEntity> userDBEntityList = GRLCDAL.GetInstance().GetUserInfoEntityList(request, out totalCount);
  11. DataResponse<UserDBEntity> dataResponse = new DataResponse<UserDBEntity>();
  12. dataResponse.DataList = userDBEntityList;
  13. dataResponse.TotalCount = totalCount;
  14. return dataResponse;
  15. }

没什么可说的,ConstValues类中是一些静态只读属性

  1. public class ConstValues
  2. {
  3. public static readonly string CON_DBConnection = ConfigurationManager.ConnectionStrings["DB_ConnectionStr"].ToString();
  4. public static readonly string CON_DbScriptXmlFolder = ConfigurationManager.AppSettings["DbScriptXmlFolder"];
  5. public static readonly int CONN_DefaultPageSize = int.Parse(ConfigurationManager.AppSettings["DefaultPageSize"]);
  6. public static readonly int CONN_DefaultPageIndex = 1;
  7. public static readonly int CONN_PagerDisplayCount = int.Parse(ConfigurationManager.AppSettings["PagerDisplayCount"]);
  8. }

看一下DAL层。

  1. public List<UserDBEntity> GetUserInfoEntityList(UserInfoRequest request, out int totalCount)
  2. {
  3. totalCount = 0;
  4. string sqlScript = string.Empty;
  5. try
  6. {
  7. sqlScript = DBScriptManager.GetScript(this.GetType(), "GetUserInfo");
  8. SqlParameter[] sqlParameters =
  9. {
  10. new SqlParameter("@IsMarried",SqlDbType.Char,1),
  11. new SqlParameter("@StartDate",SqlDbType.DateTime),
  12. new SqlParameter("@EndDate",SqlDbType.DateTime),
  13. new SqlParameter("@UserName",SqlDbType.NVarChar,20),
  14. new SqlParameter("@PageIndex",SqlDbType.Int),
  15. new SqlParameter("@PageSize",SqlDbType.Int),
  16. new SqlParameter("@TotalCount",SqlDbType.Int)
  17. };
  18. sqlParameters[0].Value = request.IsMarried;
  19. sqlParameters[1].Value = request.StartDate;
  20. sqlParameters[2].Value = request.EndDate;
  21. sqlParameters[3].Value = request.UserName;
  22. sqlParameters[4].Value = request.PageIndex;
  23. sqlParameters[5].Value = request.PageSize;
  24. sqlParameters[6].Direction = ParameterDirection.Output;
  25. DataSet ds = SqlHelper.ExecuteDataset(ConstValues.CON_DBConnection, CommandType.Text, sqlScript, sqlParameters);
  26. if (ds != null && ds.Tables.Count > 0)
  27. {
  28. totalCount = Convert.ToInt32(sqlParameters[6].Value);
  29. return ds.Tables[0].ToEntityList<UserDBEntity>();
  30. }
  31. return new List<UserDBEntity>();
  32. }
  33. catch (Exception ex)
  34. {
  35. LogHelper.WriteExceptionLog(MethodBase.GetCurrentMethod(), ex);
  36. return null;
  37. }
  38. }

OK,我们看一下这个GetUserInfo脚本,在Bruce.GRLC.DbScriptXml程序集下。

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <Scripts>
  3. <Script Key="GetUserInfo">
  4. <![CDATA[
  5. DECLARE @UserTempTable TABLE
  6. (
  7. ID INT IDENTITY(1,1) NOT NULL,
  8. UserNo CHAR(25) NOT NULL
  9. )
  10. INSERT INTO @UserTempTable
  11. (
  12. UserNo
  13. )
  14. SELECT
  15. A.UseNo
  16. FROM Bonus.dbo.[User] A WITH(NOLOCK)
  17. LEFT JOIN Bonus.dbo.UerInfo B WITH(NOLOCK)
  18. ON A.UseNo = B.UseNo
  19. WHERE (@IsMarried IS NULL OR @IsMarried = '' OR B.Temper = @IsMarried)
  20. AND
  21. (
  22. @StartDate IS NULL
  23. OR @EndDate IS NULL
  24. OR B.BirthDay BETWEEN @StartDate AND @EndDate
  25. )
  26. AND
  27. (
  28. @UserName IS NULL
  29. OR @UserName = ''
  30. OR B.Name LIKE '%' + @UserName + '%'
  31. )
  32. ORDER BY A.UseNo ASC
  33. SELECT @TotalCount = COUNT(1) FROM @UserTempTable
  34. SELECT
  35. UseNo,
  36. Name,
  37. Age,
  38. Married
  39. FROM(
  40. SELECT
  41. ID = ROW_NUMBER() OVER(ORDER BY UseNo ASC),
  42. A.UseNo,
  43. B.Name,
  44. B.Age,
  45. Married = CASE WHEN B.Temper = '1'
  46. THEN '已婚'
  47. ELSE '未婚'
  48. END
  49. FROM Bonus.dbo.[User] A WITH(NOLOCK)
  50. LEFT JOIN Bonus.dbo.UerInfo B WITH(NOLOCK)
  51. ON A.UseNo = B.UseNo
  52. INNER JOIN @UserTempTable C
  53. ON C.UserNo = A.UseNo
  54. ) N
  55. WHERE ID BETWEEN (@PageIndex - 1)* @PageSize + 1 AND @PageIndex * @PageSize
  56. ]]>
  57. </Script>
  58. </Scripts>

脚本很简单,就是传入参数查分页数据。

在DAL层我们将DataTable通过ToEntityList转化为了实体List,在Utility中我们定义了一个扩展用来转化。

  1. public static class DataTableToEntityExtension
  2. {
  3. public static List<T> ToEntityList<T>(this DataTable dt) where T : class,new()
  4. {
  5. List<T> entityList = new List<T>();
  6. Type entityType = typeof(T);
  7. PropertyInfo[] propertys = entityType.GetProperties();
  8. DataMappingAttribute mappingAttribute = null;
  9. foreach (DataRow dr in dt.Rows)
  10. {
  11. T tEntity = new T();
  12. foreach (PropertyInfo pi in propertys)
  13. {
  14. mappingAttribute = pi.GetCustomAttribute(typeof(DataMappingAttribute)) as DataMappingAttribute;
  15. if (mappingAttribute != null && dt.Columns.Contains(mappingAttribute.mappingName))
  16. {
  17. if (!pi.CanWrite) continue;
  18. object value = dr[mappingAttribute.mappingName];
  19. if (value != DBNull.Value)
  20. pi.SetValue(tEntity, value, null);
  21. }
  22. }
  23. entityList.Add(tEntity);
  24. }
  25. return entityList;
  26. }
  27. }

值那么转化的时候是怎么让DataTable的列和实体匹配起来,你可以将列别名和实体定义成一样的,还有一种你可以使用Attribute。那我们使用后者,因为后者更灵活。

  1. [AttributeUsage(AttributeTargets.Property)]
  2. public class DataMappingAttribute : Attribute
  3. {
  4. public string mappingName;
  5. public DbType dbType;
  6. public DataMappingAttribute()
  7. { }
  8. public DataMappingAttribute(string mappingName, DbType dbType)
  9. {
  10. this.mappingName = mappingName;
  11. this.dbType = dbType;
  12. }
  13. }

定义好Attribute之后,我们设置其能使用的目标只能是Property。然后我们在实体类里面的属性上加上这个Attribute。

  1. namespace Bruce.GRLC.Model.Entity
  2. {
  3. public class UserDBEntity
  4. {
  5. [DataMapping("UseNo", DbType.AnsiString)]
  6. public string UserID { get; set; }
  7. [DataMapping("Name", DbType.AnsiString)]
  8. public string UserName { get; set; }
  9. [DataMapping("Age", DbType.Int32)]
  10. public int Age { get; set; }
  11. [DataMapping("Married", DbType.String)]
  12. public string Married { get; set; }
  13. }
  14. }

在DataTableToEntityExtension这个扩展中我们得到属性的Attribute去和DataTable的列名去匹配,反射赋值。

OK,拿到数据后,我们在控制器构造viewModel,传递给界面来绑定。我们看一下部分页UserInfoPartial.cshtml的代码

  1. @using Bruce.GRLC.Model.ViewModel;
  2. @model UserInfoViewModel
  3. <table id="tabuserinfo" class="table table-bordered table-hover">
  4. <thead>
  5. <tr style="background-color: #2aabd2;color:white">
  6. <th>帐号</th>
  7. <th>姓名</th>
  8. <th>年龄</th>
  9. <th>婚否</th>
  10. </tr>
  11. </thead>
  12. <tbody>
  13. @if (Model != null && Model.DataResponse != null && Model.DataResponse.DataList != null)
  14. {
  15. foreach (var userEntity in Model.DataResponse.DataList)
  16. {
  17. <tr>
  18. <td>
  19. @userEntity.UserID
  20. </td>
  21. <td>
  22. @userEntity.UserName
  23. </td>
  24. <td>
  25. @userEntity.Age
  26. </td>
  27. <td>
  28. @userEntity.Married
  29. </td>
  30. </tr>
  31. }
  32. }
  33. </tbody>
  34. </table>
  35. <div id="divpagination">
  36. @{Html.RenderPartial("~/Views/Partial/PaginationPartial.cshtml", Model.DataResponse);}
  37. </div>

其实也就是一个应用了BoootStrap样式的表格,有边框和鼠标经过的样式。关于BootStrap的样式的使用,请参考BootStrap官网。代码很简单,就是循环遍历,展示数据。

转载于:https://www.cnblogs.com/happy-Chen/p/4915158.html

ASP.NET MVC4+BootStrap实战相关推荐

  1. Asp.net MVC4 Knockoutjs BootStrap Ace NinJect Jqgrid sqlserver2008

    Asp.net MVC4 Knockoutjs  BootStrap Ace NinJect  Jqgrid sqlserver2008 转载于:https://www.cnblogs.com/zhx ...

  2. ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存

    ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存 原文:ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存 ASP.Net MVC4+Memc ...

  3. Asp.Net Core 项目实战之权限管理系统(0) 无中生有

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  4. asp.net mvc linux,ASP.NET MVC4开发指南PDF扫描版+源码

    ASP.NET MVC问世已久,几年前或许有人会担心ASP.NET MVC框架是否能用在实务的项目上,也担心用在新项目上是否真的能改善开发效率与质量,但笔者这几年下来,已经累积数十个网站项目改用ASP ...

  5. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(12)-系统日志和异常的处理②...

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(12)-系统日志和异常的处理② 上一讲我们做了日志与异常的结果显示列表,这一节我们讲要把他应用系统中来. ...

  6. ASP.NET MVC4中调用WEB API的四个方法

    当今的软件开发中,设计软件的服务并将其通过网络对外发布,让各种客户端去使用服务已经是十分普遍的做法.就.NET而言,目前提供了Remoting,WebService和WCF服务,这都能开发出功能十分强 ...

  7. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(31)-MVC使用RDL报表

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(31)-MVC使用RDL报表 这次我们来演示MVC3怎么显示RDL报表,坑爹的微软把MVC升级到5都木有良 ...

  8. .ne中的控制器循环出来的数据如何显示在视图上_Web程序设计-ASP.NET MVC4数据库操作实例...

    ASP.NET MVC4数据库操作实例 之前文章介绍了MVC4与Pure框架结合进行的网页设计过程中如何定义控制器.方法.模型.视图等.并使用实例进行了简单说明.本文将在此基础上进一步说明如何使用MV ...

  9. 【翻译转载】【官方教程】Asp.Net MVC4入门指南(2):添加一个控制器

    2. 添加一个控制器 · 原文地址:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-c ...

最新文章

  1. 民营企业SAP项目客户的几种心态
  2. opencv学习笔记(二):基于肤色的人手检测
  3. 使用$.ajax向服务器发送请求
  4. session的钝化和活化
  5. [ python ] 基础技巧
  6. 每天Leetcode 刷题 初级算法篇-颠倒二进制位
  7. SQL SERVER 2012 第五章 创建和修改数据表 の CREATE语句
  8. java socket 局域网_javase基础socket编程之局域网聊天,局域网文件共享
  9. USB-PD 协议解析 - 简单易懂协议详解
  10. 智能手环---MQTT协议简介及协议原理
  11. 十张图带你看中国交通变迁
  12. dojo框架的基本认识
  13. 20150128-堆雪人
  14. 【bzoj3875】[Ahoi2014Jsoi2014]骑士游戏
  15. 中国历代职官科举制度
  16. Shopee关联广告和关键词广告有什么不同?如何优化广告关键词?
  17. ABAP 获取流水单号(SNRO SAP自动编号)
  18. 【PaddleSpeech-学习笔记】第七章:声音合成
  19. 当当网抄底优惠,2021年数据人都在啃的这些好书囤慢无货
  20. RHCE之搭建DNS服务器

热门文章

  1. Mybatis-Plus实战中的几个条件构造器Wrapper用法
  2. php自动处理,thinkphp中的三种自动处理
  3. asp.net多图片上传案例_会计小明的故事-成本核算案例篇
  4. 如何用计算机弹逆战6,逆战星光弹夹使用方法介绍 轻松玩转星光弹
  5. 中专是计算机专业毕业论文,中专计算机专业毕业论文内容
  6. linux文件删除漏洞,OpenStack Glance v1 API任意文件删除漏洞(CVE-2012-4573)
  7. kuka机器人焊接飞溅大_机器人专用三维焊接平台低温现象得到解决
  8. python多久更新一次_Python Tkinter,每秒钟更新一次
  9. python数据库模糊查询_python中数据库like模糊查询方式
  10. C++知识点47——类继承中的类型转换与访问权限控制(下)