【博文推荐】ASP.NET MVC4+BootStrap实战

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

ASP.NET MVC4+BootStrap实战

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

ASP.NET MVC4+BootStrap实战

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

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

ASP.NET MVC4+BootStrap 实战

其实查询条件就是婚否,出生日期,姓名的模糊查询。我们先看一下页面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, nullnew { 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的网格系统,看如下的解释

ASP.NET MVC4+BootStrap实战

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

ASP.NET MVC4+BootStrap实战

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

ASP.NET MVC4+BootStrap实战

我们看到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.   
  4. namespace Brue.GRLC.Web 
  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.   
  13.             bundles.Add(new ScriptBundle("~/bundles/Scripts").Include("~/Js/Index.js")); 
  14.   
  15.             bundles.Add(new StyleBundle("~/css").Include("~/BootStrap/css/bootstrap-theme.css" 
  16.                 , "~/BootStrap/css/bootstrap.css")); 
  17.         } 
  18.     } 

注意,在这里引用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.   
  7.             DataResponse<UserDBEntity> dataResponse = GRLCBiz.GetInstance().GetUserInfoEntityList(); 
  8.             UserInfoViewModel userInfoViewModel = new UserInfoViewModel(); 
  9.             userInfoViewModel.DataResponse = dataResponse; 
  10.             userInfoViewModel.DataResponse.PageIndex = ConstValues.CONN_DefaultPageIndex; 
  11.             userInfoViewModel.DataResponse.PageSize = ConstValues.CONN_DefaultPageSize; 
  12.             userInfoViewModel.DataResponse.StartPageIndex = 1
  13.             return View(userInfoViewModel); 
  14.         } 

首先我们构造了一个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.   
  8.             return marriedList; 
  9.         } 

用匿名类去构造一个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.             
  10.             int totalCount=0
  11.   
  12.             List<UserDBEntity> userDBEntityList = GRLCDAL.GetInstance().GetUserInfoEntityList(request, out totalCount); 
  13.             DataResponse<UserDBEntity> dataResponse = new DataResponse<UserDBEntity>(); 
  14.             dataResponse.DataList = userDBEntityList; 
  15.             dataResponse.TotalCount = totalCount; 
  16.             return dataResponse; 
  17.         } 

没什么可说的,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.   
  19.                 sqlParameters[0].Value = request.IsMarried; 
  20.                 sqlParameters[1].Value = request.StartDate; 
  21.                 sqlParameters[2].Value = request.EndDate; 
  22.                 sqlParameters[3].Value = request.UserName; 
  23.                 sqlParameters[4].Value = request.PageIndex; 
  24.                 sqlParameters[5].Value = request.PageSize; 
  25.                 sqlParameters[6].Direction = ParameterDirection.Output; 
  26.   
  27.                 DataSet ds = SqlHelper.ExecuteDataset(ConstValues.CON_DBConnection, CommandType.Text, sqlScript, sqlParameters); 
  28.                 if (ds != null && ds.Tables.Count > 0
  29.                 { 
  30.                     totalCount = Convert.ToInt32(sqlParameters[6].Value); 
  31.                     return ds.Tables[0].ToEntityList<UserDBEntity>(); 
  32.                 } 
  33.   
  34.                 return new List<UserDBEntity>(); 
  35.             } 
  36.             catch (Exception ex) 
  37.             { 
  38.                 LogHelper.WriteExceptionLog(MethodBase.GetCurrentMethod(), ex); 
  39.                 return null
  40.             } 
  41.         } 

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

ASP.NET MVC4+BootStrap实战

 
 
  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.     UserNo 
  12. SELECT 
  13.     A.UseNo 
  14. FROM Bonus.dbo.[User] A WITH(NOLOCK) 
  15. LEFT JOIN Bonus.dbo.UerInfo B WITH(NOLOCK) 
  16.     ON A.UseNo = B.UseNo 
  17. WHERE (@IsMarried IS NULL OR @IsMarried = '' OR B.Temper = @IsMarried
  18.     AND 
  19.     ( 
  20.         @StartDate IS NULL  
  21.         OR @EndDate IS NULL  
  22.         OR B.BirthDay BETWEEN @StartDate AND @EndDate 
  23.     ) 
  24.     AND  
  25.     ( 
  26.         @UserName IS NULL  
  27.         OR @UserName = ''  
  28.         OR B.Name LIKE '%' + @UserName + '%' 
  29.     ) 
  30. ORDER BY A.UseNo ASC 
  31.       
  32. SELECT @TotalCount = COUNT(1) FROM @UserTempTable 
  33.   
  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.   
  7.             Type entityType = typeof(T); 
  8.             PropertyInfo[] propertys = entityType.GetProperties(); 
  9.             DataMappingAttribute mappingAttribute = null
  10.   
  11.             foreach (DataRow dr in dt.Rows) 
  12.             { 
  13.                 T tEntity = new T(); 
  14.   
  15.                 foreach (PropertyInfo pi in propertys) 
  16.                 { 
  17.                     mappingAttribute = pi.GetCustomAttribute(typeof(DataMappingAttribute)) as DataMappingAttribute; 
  18.   
  19.                     if (mappingAttribute != null && dt.Columns.Contains(mappingAttribute.mappingName)) 
  20.                     {  
  21.                         if (!pi.CanWrite) continue
  22.   
  23.                         object value = dr[mappingAttribute.mappingName]; 
  24.                         if (value != DBNull.Value) 
  25.                             pi.SetValue(tEntity, value, null); 
  26.                     } 
  27.                 } 
  28.                 entityList.Add(tEntity); 
  29.             } 
  30.             return entityList; 
  31.         } 
  32.     } 

值那么转化的时候是怎么让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.   
  9.         public DataMappingAttribute(string mappingName, DbType dbType) 
  10.         { 
  11.             this.mappingName = mappingName; 
  12.             this.dbType = dbType; 
  13.         } 
  14.     } 

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

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

在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官网。代码很简单,就是循环遍历,展示数据。


作者:BruceAndLee

来源:51CTO

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值