好久沒有寫關于web開發(fā)的文章了,進到這個公司一直就是winform和Silverlight,實在是沒有實戰(zhàn)web項目的機會。大D也辭職了,去搞web app了。自己也該閑暇時間多學習學習,每天進步一點點。
創(chuàng)新互聯是專業(yè)的鹿邑網站建設公司,鹿邑接單;提供成都網站設計、成都網站制作,網頁設計,網站設計,建網站,PHP網站建設等專業(yè)做網站服務;采用PHP框架,可快速的進行鹿邑網站開發(fā)網頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網站,專業(yè)的做網站團隊,希望更多企業(yè)前來合作!
OK,不多說了,看一下Solution的截圖
基本上一看就明白了,控制器調用Biz層,Biz層調用DAL層,DAL層進行數據的CURD。Utility是一些公用的類庫。ok,為什么程序集的命名都是以Bruce開頭呢,因為我在公司的英文名叫這個。廢話不多說,我們先看一下頁面
我們引入了BootStrap,主要是為了頁面布局。在Views中Partial下面放的都是部分頁。
我們先看一下運行效果,今天主要是講頁面初始化部分。
其實查詢條件就是婚否,出生日期,姓名的模糊查詢。我們先看一下頁面Index.cshtml的代碼
Compare data between Solr and DB @*@Styles.Render("~/css")*@ @Scripts.Render("~/bundles/BootStrap") @Scripts.Render("~/bundles/Scripts")
我們使用html5+BootStrap布局,這里用到了BootStrap的網格系統(tǒng),將瀏覽器平分為12份,即12列,很容易構造出響應式布局系統(tǒng)。那么什么是BootStrap的網格系統(tǒng),看如下的解釋
OK,我們怎么看是否是響應式的布局呢,我們打開谷歌瀏覽器,現將瀏覽器縮小到一定程度。
看到了吧,即使設備瀏覽器這么小,我們還是能用。那我們在手機模擬器中測試一下,打開谷歌瀏覽器,按F12,點擊手機模擬器樣的東西,然后Device選擇iphone6。
我們看到iphone6下面的效果是這樣的。說到這里我最近很討厭兩個廣告,一個是“這個是iphone6,這個是iphone6 plus,它們都有一個叫健康的東西.....但是好吃啊”,還有一個是“當牛魔王變成一個餃子,我愿意變成一雙筷子”。看到這兩個廣告,我想砸電視。
那為什么不同的設備不同的瀏覽器都是可以正常瀏覽的呢,原因就在于這段代碼
這段代碼的意思是網頁寬度默認等于屏幕寬度,縮放比例默認為1(網頁初始比例占屏幕的100%)。
ok,我們接下來看head部分css和js的引用,這里有個新東西叫Bundle,用來打包壓縮js或者css的。通過它打包壓縮的js或者css客戶端只需要下載一次包即可,而且可以在客戶端緩存起來,當檢測到有更新時,才會重新下載。
下面是Bundle.cs的代碼
using System.Web; using System.Web.Optimization; namespace Brue.GRLC.Web { public class BundleConfig { // 有關 Bundling 的詳細信息,請訪問 http://go.microsoft.com/fwlink/?LinkId=254725 public static void RegisterBundles(BundleCollection bundles) { bundles.Add(new ScriptBundle("~/bundles/BootStrap").Include( "~/Scripts/jquery-1.11.1.js","~/BootStrap/js/bootstrap.js")); bundles.Add(new ScriptBundle("~/bundles/Scripts").Include("~/Js/Index.js")); bundles.Add(new StyleBundle("~/css").Include("~/BootStrap/css/bootstrap-theme.css" , "~/BootStrap/css/bootstrap.css")); } } }
注意,在這里引用js的時候不要引用壓縮過的js,比如xxx.min.js。當Bundle在遇到這種js命名文件的時候,直接就忽略掉了。那么我們在Head中只需要使用如下代碼來引用即可。
@Scripts.Render("~/bundles/BootStrap") @Scripts.Render("~/bundles/Scripts")
OK,在這我碰到一個問題,就是我的css通過這種方式引用,始終提示Index out of range。如果哪位大牛知道原因的話麻煩留個言,謝謝!
OK,我們接下來看一下控制器代碼,頁面剛進來,會走Home/Index。
public ActionResult Index() { List
首先我們構造了一個SelectList用于下拉列表,Biz層的代碼很簡單
public dynamic GetMarriedList() { IList
用匿名類去構造一個List。接下來就是DataReponse的獲取,Biz層的代碼如下
public DataResponseGetUserInfoEntityList(UserInfoRequest request = null) { if(request==null) { request = new UserInfoRequest(); request.PageIndex = ConstValues.CONN_DefaultPageIndex; request.PageSize = ConstValues.CONN_DefaultPageSize; } int totalCount=0; List userDBEntityList = GRLCDAL.GetInstance().GetUserInfoEntityList(request, out totalCount); DataResponse dataResponse = new DataResponse (); dataResponse.DataList = userDBEntityList; dataResponse.TotalCount = totalCount; return dataResponse; }
沒什么可說的,ConstValues類中是一些靜態(tài)只讀屬性
public class ConstValues { public static readonly string CON_DBConnection = ConfigurationManager.ConnectionStrings["DB_ConnectionStr"].ToString(); public static readonly string CON_DbScriptXmlFolder = ConfigurationManager.AppSettings["DbScriptXmlFolder"]; public static readonly int CONN_DefaultPageSize = int.Parse(ConfigurationManager.AppSettings["DefaultPageSize"]); public static readonly int CONN_DefaultPageIndex = 1; public static readonly int CONN_PagerDisplayCount = int.Parse(ConfigurationManager.AppSettings["PagerDisplayCount"]); }
看一下DAL層。
public ListGetUserInfoEntityList(UserInfoRequest request, out int totalCount) { totalCount = 0; string sqlScript = string.Empty; try { sqlScript = DBScriptManager.GetScript(this.GetType(), "GetUserInfo"); SqlParameter[] sqlParameters = { new SqlParameter("@IsMarried",SqlDbType.Char,1), new SqlParameter("@StartDate",SqlDbType.DateTime), new SqlParameter("@EndDate",SqlDbType.DateTime), new SqlParameter("@UserName",SqlDbType.NVarChar,20), new SqlParameter("@PageIndex",SqlDbType.Int), new SqlParameter("@PageSize",SqlDbType.Int), new SqlParameter("@TotalCount",SqlDbType.Int) }; sqlParameters[0].Value = request.IsMarried; sqlParameters[1].Value = request.StartDate; sqlParameters[2].Value = request.EndDate; sqlParameters[3].Value = request.UserName; sqlParameters[4].Value = request.PageIndex; sqlParameters[5].Value = request.PageSize; sqlParameters[6].Direction = ParameterDirection.Output; DataSet ds = SqlHelper.ExecuteDataset(ConstValues.CON_DBConnection, CommandType.Text, sqlScript, sqlParameters); if (ds != null && ds.Tables.Count > 0) { totalCount = Convert.ToInt32(sqlParameters[6].Value); return ds.Tables[0].ToEntityList (); } return new List (); } catch (Exception ex) { LogHelper.WriteExceptionLog(MethodBase.GetCurrentMethod(), ex); return null; } }
OK,我們看一下這個GetUserInfo腳本,在Bruce.GRLC.DbScriptXml程序集下。
腳本很簡單,就是傳入參數查分頁數據。
在DAL層我們將DataTable通過ToEntityList轉化為了實體List,在Utility中我們定義了一個擴展用來轉化。
public static class DataTableToEntityExtension { public static ListToEntityList (this DataTable dt) where T : class,new() { List entityList = new List (); Type entityType = typeof(T); PropertyInfo[] propertys = entityType.GetProperties(); DataMappingAttribute mappingAttribute = null; foreach (DataRow dr in dt.Rows) { T tEntity = new T(); foreach (PropertyInfo pi in propertys) { mappingAttribute = pi.GetCustomAttribute(typeof(DataMappingAttribute)) as DataMappingAttribute; if (mappingAttribute != null && dt.Columns.Contains(mappingAttribute.mappingName)) { if (!pi.CanWrite) continue; object value = dr[mappingAttribute.mappingName]; if (value != DBNull.Value) pi.SetValue(tEntity, value, null); } } entityList.Add(tEntity); } return entityList; } }
值那么轉化的時候是怎么讓DataTable的列和實體匹配起來,你可以將列別名和實體定義成一樣的,還有一種你可以使用Attribute。那我們使用后者,因為后者更靈活。
[AttributeUsage(AttributeTargets.Property)] public class DataMappingAttribute : Attribute { public string mappingName; public DbType dbType; public DataMappingAttribute() { } public DataMappingAttribute(string mappingName, DbType dbType) { this.mappingName = mappingName; this.dbType = dbType; } }
定義好Attribute之后,我們設置其能使用的目標只能是Property。然后我們在實體類里面的屬性上加上這個Attribute。
namespace Bruce.GRLC.Model.Entity { public class UserDBEntity { [DataMapping("UseNo", DbType.AnsiString)] public string UserID { get; set; } [DataMapping("Name", DbType.AnsiString)] public string UserName { get; set; } [DataMapping("Age", DbType.Int32)] public int Age { get; set; } [DataMapping("Married", DbType.String)] public string Married { get; set; } } }
在DataTableToEntityExtension這個擴展中我們得到屬性的Attribute去和DataTable的列名去匹配,反射賦值。
OK,拿到數據后,我們在控制器構造viewModel,傳遞給界面來綁定。我們看一下部分頁UserInfoPartial.cshtml的代碼
@using Bruce.GRLC.Model.ViewModel; @model UserInfoViewModel
帳號 | 姓名 | 年齡 | 婚否 |
---|---|---|---|
@userEntity.UserID | @userEntity.UserName | @userEntity.Age | @userEntity.Married |
其實也就是一個應用了BoootStrap樣式的表格,有邊框和鼠標經過的樣式。關于BootStrap的樣式的使用,請參考BootStrap官網。代碼很簡單,就是循環(huán)遍歷,展示數據。