【博文推荐】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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Combine the power of ASP.Net MVC 6 with Bootstrap 4 to build elegant, responsive web apps About This Book Updated for Bootstrap 4 and ASP.Net MVC 6, this book shows how to take advantage of the latest new features introduced in both of these industry-leading frameworks Build responsive, mobile-ready apps by combining the power of ASP.NET MVC with Bootstrap Grasp the intricacies of Bootstrap and how to use it with ASP.NET MVC Build your own tools and helpers to assist you in creating ASP.NET MVC Bootstrap sites easily and quickly Master the use of Bootstrap components and plugins with ASP.NET MVC Who This Book Is For If you are an ASP.NET MVC developer and would like to know how to incorporate Bootstrap into your projects, then this book is invaluable to you. Developers with entry-level experience of ASP.NET MVC development and limited experience with Bootstrap will also benefit from this book. What You Will Learn Create a new ASP.Net MVC 6 project that uses Bootstrap for its styling and learn how to include external libraries using the new package managers Learn to use the various Bootstrap CSS and HTML elements, and how to use the new Bootstrap 4 grid layout system with ASP.Net MVC Explore the different input groups and implement alerts, progress bars, and badges Explore JavaScript components by illustrating and walking through the process of using JavaScript/JQuery to add interactivity to Twitter Bootstrap components Build your own ASP.Net MVC helpers and tag helpers to reduce the amount of HTML needed to generate Bootstrap elements in your projects Convert a Bootstrap HTML template into a usable ASP.Net MVC project Use the jQuery DataTables plugin with Bootstrap and ASP.Net MVC Learn to include and use the TwitterBootstrapMVC library in an ASP.Net MVC project In Detail One of the leading open source frontend frameworks, Bootstrap has undergone a significant change and introduced several features that make designing compelling, next-generation UIs much simpler.
包括源代码、数据库文档、数据库创建SQL脚本。一套基于ASP.NET MVC+EF6+Bootstrap开发出来的框架源代码! 采用主流框架,容易上手,简单易学,学习成本低。可完全实现二次开发、基本满足80%项目需求。 可以帮助解决.NET项目70%的重复工作,让开发更多关注业务逻辑。既能快速提高开发效率,帮助公司节省人力成本,同时又不失灵活性。 支持SQLServer、MySQL、Oracle、SQLite、Access 等多数据库类型。模块化设计,层次结构清晰。内置一系列企业信息管理的基础功能。 操作权限控制精密细致,对所有管理链接都进行权限验证,可控制到导航菜单、功能按钮。 数据权限(精细化数据权限控制,控制到行级,列表级,表单字段级,实现不同人看不同数据,不同人对同一个页面操作不同字段 兼容目前最流行浏览器(IE8+、Chrome、Firefox、360浏览器) 1、前端技术 JS框架:Bootstrap、JQuery CSS框架:Bootstrap v3.3.4(稳定是后台,UI方面根据需求自己升级改造吧)。 客户端验证:jQuery Validation Plugin。 在线编辑器:ckeditor、simditor 上传文件:Uploadify 数据表格:jqGrid、Bootstrap Talbe 对话框:layer 页面布局:jquery.layout.js 图表插件:echarts、highcharts 2、后端技术 核心框架:ASP.NET MVC5、WEB API 持久层框架:EntityFramework 定时计划任务:Quartz.Net组件 安全支持:过滤器、Sql注入、请求伪造 服务端验证:实体模型验证、自己封装Validator 缓存框架:微软自带Cache、Redis 日志管理:Log4net、登录日志、操作日志 工具类:NPOI、Newtonsoft.Json、验证码

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值