圖書商城項目總論


圖書商城項目總論

這些年來,我隨指南針公司做了一些網站。在這里也感謝指南針用戶對鄙人的大力支持,厚愛。匯聚很多程序員多年的智慧,今天我把多年來積累的經驗匯聚到一個圖書商城項目里面,為大家介紹網站的源代碼。關鍵的環節在於融會貫通,舉一反三。

先從注冊開始,注冊說起來相對來比較簡單

      

一、登錄界面

注冊界面里面有文本框,有用戶名的檢測 – 用到“AJAX”這個知識點

填寫完信息點擊注冊后,有個js或是jq的校驗

當信息全部填寫完,用戶點擊注冊按鈕后,把表單里面的數據向服務端提交,在服務端接收數據,插入數據庫。

 

那么,除了把用戶信息插入數據庫當中之外,我們還要實現用戶激活的功能。就是獲取用戶輸入郵箱,根據郵箱發一封郵件。郵件的內容就是激活鏈接。

 

把用戶信息寫入數據庫相對簡單,問題是怎么去發郵件,怎么發激活鏈接?這是我們重點講解的內容。介紹怎么知道用戶點沒點鏈接,怎樣進行激活。

 

接下來做的一個功能就是找回密碼功能。

 

二、找回密碼演示界面

根據用戶的郵箱,把用戶名和密碼發給用戶。這也是我們重點講解的內容。

這部分用到了之前我們講解的緩存。

接下來我們做下用戶注冊之后上傳頭像的功能,

以前我們上傳的時候可能用的是<input type=”File”>但是用戶的體驗度不是特別的好,為什么呢?<input type=”submit”>一點submit就刷新了。

我們要做個無刷新上傳。講解兩種方式,重點介紹flash開源的組件。

 

 

 

 

 

三、無刷新上傳演示

上傳之后,完成截取功能。

 

四、頭像截取功能介紹

講解flash組件的使用,上傳的服務端代碼,jq和js實現截取,獲取坐標。

然后實現登錄功能:

 

五、登錄功能介紹

這里要實現用戶名,密碼的校驗,實現:“記住我”的功能。記住我使用cookie。

這塊說完了之后,我們再說下AJAX的登錄模式。

 

 

 

 

 

 

 

 

六、AJAX登錄模式

以及遮罩效果,遮罩我們使用jq來實現。

下一步我們看下:圖書列表的展示,我們怎樣用美工做好的html網頁,怎么樣把數據從數據庫中拿出來並且進行綁定。

具體實現步驟,從服務端獲取相關數據,綁定以及分頁的實現。排序的基本實現,還會詳細探討下viewstate。

 

七、圖書列表展示

 

八、分頁效果一

 

九、另外一種分頁的模式

看完另外一種分頁的形式后,我們看下url重新問題。

 

十、url重寫

並且深入探討url重寫問題。url重寫主要就是為了SEO網站優化的問題。

接下來看下怎么生成靜態頁:

 

十一、生成靜態頁

也就是純html網頁,當用戶量比較大的時候,我們最好做成靜態頁。

然后再看下評論的發布。

 

十二、評論的發布

這里要實現評論的發布,以及評論內容的加載。重點關注的是時間問題,非具體時間的顯示。請仔細看下我們評論區域,不是普通的文本編輯器,是個ubb的文本編輯器。

在這里還要看下xss跨站點腳本攻擊的問題和敏感詞過濾問題(禁用詞,審查詞,替換詞)。關於審查詞,如:發票。這兩個字先提交到數據庫,管理員進行審核。

接下來的內容自己可以做了,就是評論內容的無刷新分頁。

還有就是當滾動條滾動到頁面的最下端的時候,才顯示評論信息的功能。

這些都講解完成后,進入購物車功能:

 

十三、購物車功能

  在這里實現商品的增加,商品的遞減,商品的刪除一系列功能。用jq或js完成。

  接下來我們完成結算的功能講解。

 

十四、結算功能

 進入到訂單確認頁面里面,輸入收貨人的地址,選擇支付方式,在這里重點講解怎么實現支付寶。當然在這里我們使用的是模擬的支付寶系統,帶大家理解下原理,以及流程。

 接下來就到結算功能了,在這里用戶要完成下訂單操作,向支付寶發送數據的功能。

 介紹完這部分內容以后,我們再詳細的介紹下編輯器。

 

十五、編輯器

  在這里我們要了解下它的基本使用,再帶大家學習詞庫

 

十六、詞庫

  要實現敏感詞的過濾功能的話,在我們的系統里面必須得有個詞庫。在這里我們講解下詞庫的添加與下載。

  接下來我們再講解下日志記錄問題。用到一個開源的框架。

  再來介紹下開源的定時框架。就是每隔多長時間去執行什么任務。比如:每天一個約定時間去統計今天的訂單數。

  這些介紹完以后,我們再來介紹下SEO的問題。

  最后的文章里面會給大家介紹下視頻處理的問題,就是怎么樣做視頻的播放的問題。當用戶上傳任意的格式的視頻的時候我們怎么樣進行轉換。轉完以后又怎么播放。

 

 

 

 

 

 

 

十七、播放有關內容

  接下來再說下權限管理的內容:

  這塊我們單獨的進行演示

 

十八、權限管理系統

 

十九、權限管理-用戶管理

  當admin管理員進入的時候,可以展示出所有的菜單。管理員可以添加新的用戶,添加完用戶以后可以給這個用戶添加角色。

 

二十、權限管理-角色管理

  然后為這個角色指定權限。

 

二十一、為角色指定權限

  以及菜單管理。

 

二十二、菜單管理

  菜單用戶可以進行添加。

 

二十三、添加菜單

  然后菜單項也是與權限相關聯的。當管理員登陸的時候,菜單全部展開,普通用戶登錄,只能展示出相應的菜單。所以說,菜單也有權限編號。當用戶登錄的時候拿到菜單的權限編號和用戶的權限編號進行對比,來決定顯示哪個菜單。

 

好,總論講解完畢,下面進入詳細環節。先看下權限管理內容。

權限表分析:在權限管理里面最重要的是三個對象,用戶管理對象,角色管理對象,權限管理對象。這里就用到了面向對象的思想。

請看下面的圖示:

 

二十四、權限管理數據庫分析

先看下名詞解釋,用戶很好理解。什么叫角色呢?老師,學生都是角色。權限也比較的好理解。

在這里用戶為什么沒有跟權限直接的進行關聯呢?

用戶要和角色進行關聯,用戶屬於某個角色。在這里舉個例子講解:楊川川入職了,就是個新員工,公司里面有個打卡系統,經理要開給楊川川在辦公系統開個賬戶。現在公司決定新入職的員工權限提升一次,之前5個權限,現在6個權限。假如說系統在設計的時候是用戶和權限直接關聯的。本月來的10個新員工,都要調整權限。但是用戶要是和角色相關聯的話,這時,只要把新員工的權限改下就行了。所有屬於新員工的用戶權限就都發生變化了。

下面我們就看下權限的數據庫怎么進行設計了,最基本的得有用戶表,角色表,權限表。

用戶表里面有哪幾個字段呢?

用戶編號,用戶名,密碼,性別,郵件。

角色表里面有哪幾個字段呢?

角色編號,角色名。

權限表里面有哪幾個字段呢?

權限編號,權限名。

用戶跟角色進行關聯,按照我們之前講解的內容,兩個表就有關系了。主外建關系。如果我在用戶表里面加個角色編號的話,你們認為合理么?

一個用戶屬於一個角色,一個角色下可以有多個用戶,所以說這兩個表的關系就是多對多的關系。既然是多對多的關系,我們怎么表現出這種關系呢?

還得需要一張表,就是用戶角色關系表。用戶和角色的關系就體現在用戶關系角色表里面了。

用戶關系角色表里面應該有哪些字段呢?

用戶編號,角色編號。

角色表跟權限表是個什么關系呢?

也是個多對多的關系,所以,再建一張表,叫做角色權限關系表。

這張表中有:角色編號,權限編號的字段。

這五張表就是我們的核心表了,還有一張我多增加的表叫做權限類別表。然后權限都放在一個大類下面。

有:類別編號,類別名稱字段。

在權限表中,增加個:類別編號的字段。

 

二十五、數據庫當中的六張表

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

二十六、權限管理模塊核心表結構

我們看到還有像菜單表,用戶信息表中還有部門這樣的字段。剛才的六張表的分析,以思路為主,采用的字段都是最基本的字段。

剛才我們分析了數據表的創建過程,關鍵是思路,能理解這個過程就可以了.

下一步我們開始設計登錄的內容,打開項目,我們先用手寫的三層,后面講到圖書商城項目的時候再演示代碼生成器.

 

 

 

 

 

 

 

 

二十七、web登錄(1)

 

二十八、放驗證碼的位置

驗證碼插入位置:

View Code
 1 using System;
 2 using System.Collections;
 3 using System.Data;
 4 using System.Linq;
 5 using System.Web;
 6 using System.Web.Services;
 7 using System.Web.Services.Protocols;
 8 using System.Xml.Linq;
 9 using System.Drawing;
10 using System.Drawing.Drawing2D;
11 namespace Web
12 {
13     /// <summary>
14     /// $codebehindclassname$ 的摘要說明
15     /// </summary>
16     [WebService(Namespace = "http://tempuri.org/")]
17     [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
18     public class ValidateCode : IHttpHandler,System.Web.SessionState.IRequiresSessionState
19         //3.在一般處理程序中使用session要實現這個接口。
20     {
21 
22         public void ProcessRequest(HttpContext context)
23         {
24             context.Response.ContentType = "image/Gif";
25             CreateStr(CreateCode());
26           
27         }
28         private string CreateCode()
29         {
30             string str = "";
31             //1.隨機生成一個數字
32             Random random = new Random();
33             str=random.Next(1000,9999).ToString();
34             //2.把數字放在個session里面。
35             HttpContext.Current.Session["code"] = str;
36             return str;
37         }
38         private void CreateStr(string code)
39         {
40             if (code.Length<= 0)
41                 return;
42             string str;
43             Random random=new Random();
44             using (Bitmap map = new Bitmap(4 * 14, 30))
45             {
46                 using (Graphics g = Graphics.FromImage(map))
47                 {
48                     g.Clear(Color.White);
49                     g.DrawRectangle(new Pen(Color.Gray), 0, 0, map.Width - 1, map.Height - 1);
50                     using (LinearGradientBrush brush = new LinearGradientBrush(new Point(0, 0), new Point(map.Width, map.Height), Color.Red, Color.Green))
51                     {
52                         for (int i = 0; i < code.Length; i++)
53                         {
54                             str = code.Substring(i, 1);
55                             g.DrawString(str, new Font("黑體", 14.0f, FontStyle.Bold), brush, new PointF(13.0f * i, random.Next(10)));
56                         }
57                         //for(int i=0;i<10;i++;)
58                         //{
59 
60                         //}
61                         for (int i = 0; i < 10; i++)
62                         {
63                             map.SetPixel(random.Next(map.Width), random.Next(map.Height), Color.FromArgb(random.Next(255), random.Next(255), random.Next(255)));
64                         }
65                         HttpContext.Current.Response.Clear();
66                         System.IO.MemoryStream stream = new System.IO.MemoryStream();
67                         map.Save(stream, System.Drawing.Imaging.ImageFormat.Gif);
68                         HttpContext.Current.Response.BinaryWrite(stream.ToArray());
69                     }
70                 }
71             }
72 
73         }
74 
75         public bool IsReusable
76         {
77             get
78             {
79                 return false;
80             }
81         }
82     }
83 }

下一步我們怎么把驗證碼放到登錄頁面上,我們該怎么放呢?

 

二十九、將驗證碼引入-用個img標簽

接下來我點驗證碼的時候需要個切換效果,這個效果怎么實現呢?

我們用js來實現,我在這加了個a標簽,在a標簽里面寫了個onclick

在js的函數里面怎么寫呢?獲取驗證碼的id,然后改變src屬性,獲取隨機數加個毫秒數,這樣第一步就完成了。

 

三十、切換驗證碼的代碼

下一步我們就開始點擊:登錄按鈕

現在我們在后台,后台的用戶訪問少,所以這里可以用服務端控件。

 

三十一、構建三層的時候需要注意的地方

 

三十二、DbHelperSQL

 

 

動軟的代碼生成器,把數據庫連接字符串都放在appSettings里面了。不要放在這里面,因為ms為我們提供了connectionStrings。

那么我們在什么時候會用到appSettings里的鍵值對呢?比如分頁,每頁顯示多少條記錄,以前都寫在程序里面。用戶不想一頁顯示10條的話,我們只能再改程序。

最好的方式是寫在配置文件里面,不需要改源代碼。我們可以把關於每頁顯示多少頁的項,放在appSettings里面。 ConfigurationManager.AppSettings["key"]獲取一下。

 

三十三、配置文件中需要注意的地方

  其實,把經常變動的內容放在配置文件中也不是最佳的選擇。如果現在網站正在服務器運行的情況下,正在使用這套程序的用戶的會話丟了。最好的解決方式就是做個頁面。可以在自己網站的后台做個頁面,這個后面馬上就講。

像使用的數據庫變化了這樣的問題,涉及到抽象工廠。就是面向接口編程。建議看下《大話設計模式》。

 

三十四、配置頁面

 

三十五、數據訪問層我們回顧的內容

 

三十六、用戶校驗的DAL層代碼

別忘了引用下model

下面寫下業務邏輯層

 

三十七、用戶校驗的BLL層代碼

  這里的BLL就是個打醬油的,別忘了引用DAL和Model。

接下來終於回到了web層。

引用bLL和Model,注意:每寫完一層,我們都需要重新生成一下。

插入代碼位置:

View Code
 1 using System;
 2 using System.Collections;
 3 using System.Configuration;
 4 using System.Data;
 5 using System.Linq;
 6 using System.Web;
 7 using System.Web.Security;
 8 using System.Web.UI;
 9 using System.Web.UI.HtmlControls;
10 using System.Web.UI.WebControls;
11 using System.Web.UI.WebControls.WebParts;
12 using System.Xml.Linq;
13 
14 namespace Web
15 {
16     public partial class Login : System.Web.UI.Page
17     {
18         protected void Page_Load(object sender, EventArgs e)
19         {
20         }
21         /// <summary>
22         /// 登錄
23         /// </summary>
24         /// <param name="sender"></param>
25         /// <param name="e"></param>
26         protected void btnLogin_Click1(object sender, ImageClickEventArgs e)
27         {
28             //1:判斷驗證碼
29             if (Session["code"] != null)
30             {
31                 if (Session["code"].ToString()== this.validateCode.Text)//拿到驗證碼的值。要是驗證碼中含有字母的話,不考慮大小寫.tolower(),驗證碼的目的主要是防止機器注冊。
32                 {
33                     //2:判讀用戶名密碼
34                     string txtName = this.txtUsername.Text;//獲取用戶名
35                     string txtPass = this.txtPassword.Text;//獲取密碼
36 
37                    
38                     //開始校驗,寫個數據訪問層,業務邏輯層
39                     BLL.Account_UserManager bll = new BLL.Account_UserManager();
40                     int userID=bll.CheckLogin(txtName, txtPass);//對用戶進行校驗,返回用戶編號
41                     if (userID > 0)//登錄成功
42                     {
43                         //對的話,記錄下用戶的信息
44                         Session["User"] = txtName;
45                         Session["UserID"] = userID;
46                         //跳轉
47                         Response.Redirect("Manage/Main.htm");
48                     }
49                     else
50                     {
51                         this.lblMsg.Text = "用戶名密碼錯誤!";
52                     }
53 
54                 }
55                 else
56                 {
57                     this.lblMsg.Text = "驗證碼錯誤!";
58                 }
59 
60             }
61             else
62             {
63                 this.lblMsg.Text = "驗證碼錯誤!";
64             }
65         }
66     }
67 }

下面我們重點討論下:session

session的主要作用就是記錄用戶登錄信息,為什么要放進session,干什么用呢?在后台的頁面里面進行校驗。

 

三十八、新建test頁

這個網頁只有登錄的用戶才可以看,

 

三十九、登錄測試頁面

  網站管理員操作的后台頁面有很多,在每個頁面加這段代碼的話,自己累,用戶也非常的不爽。我們有什么好的方法處理這個問題么?

可以用過濾器:HttpModule---其中最核心的就是19個事件。

 

四十、19個事件

  看表,得知使用第九個。如何使用這張表:由於每一個動態頁面都會走過濾器,我們就可以在過濾器里面進行判斷。過濾器有19個事件,我們一查表發現是第9個。

  那么,我們怎么去使用第9個事件呢?

 可以自己定義個類,來繼承HttpModule這個接口,也可以在全局配置文件里面,到底使用哪種方式,隨便你.

下面我寫好了這段代碼,分享源代碼貢大家使用:

插入CheckAdminModule.cs位置:

View Code
 1 using System;
 2 using System.Data;
 3 using System.Configuration;
 4 using System.Linq;
 5 using System.Web;
 6 using System.Web.Security;
 7 using System.Web.UI;
 8 using System.Web.UI.HtmlControls;
 9 using System.Web.UI.WebControls;
10 using System.Web.UI.WebControls.WebParts;
11 using System.Xml.Linq;
12 
13 namespace Web.Common
14 {
15     //1.自己定義個類繼承自IHttpModule
16     public class CheckAdminModule:IHttpModule
17     {
18         #region IHttpModule 成員
19 
20         //2.IHttpModule里面有個主要的方法Init ,參數是HttpApplication。這就是我們的請求管道。
21         public void Init(HttpApplication context)
22           //3.獲取第9個事件,通過委托調OnRequest這個方法
23         {
24             context.AcquireRequestState+=new EventHandler(OnRequest);
25            
26         }
27         //4.看下這個方法怎么做的呢?
28         public void OnRequest(object source, EventArgs e)
29         {
30             HttpApplication application = source as HttpApplication;//得到Application
31             HttpContext context = application.Context;//得到請求上下文.
32             Uri url = context.Request.Url;//得到當前請求的URL
33              
34             //5.請求Admin目錄下的文件時,需要進行身份驗證,只有管理員才能訪問.
35             //6.為什么做個判斷呢?就是我的后台的管理頁面都要放在單獨的文件夾里面,放在了admin里面了。如果下一步請求admin文件夾下的文件的話,肯定會帶文件夾的名字。就判斷一下這個路徑里面有沒有admin?有的話,就是請求的admin
36             if (url.AbsolutePath.ToLower().StartsWith("/admin"))
37             {
38                 //adminlogin.aspx和logout.aspx不需要身份驗證
39                 //7.如果是的話,再判斷一下,這個路徑的末尾包不包含:adminlogin.aspx。包含的話,可以訪問
40                 if (url.AbsolutePath.ToLower().EndsWith("adminlogin.aspx"))
41                 {
42                     return;
43                 }
44                 //退出
45                 if (url.AbsolutePath.ToLower().EndsWith("loginout.aspx"))
46                 {
47                     return;
48                 }
49                 //8.如果是admin下的一個文件但不是登陸退出的話,下一步就校驗session,如果session為空的話,直接跳到登陸頁面就行了。
50                 if (HttpContext.Current.Session["Name"] == null)
51                 {
52                     HttpContext.Current.Response.Redirect("adminlogin.aspx");
53                 }
54 
55 
56             }
57         }
58 
59         public void Dispose()
60         {
61             throw new NotImplementedException();
62         }
63 
64         #endregion
65     }
66 }

關鍵是配置項,我們要在Web.config里面配置一下。

                       

四十一、Web.config

上面的內容中我們把登錄給大家寫了一下,接着我們看下登錄成功以后

 

四十二、跳轉一

 

四十三、跳轉二

 

四十四、然后看看Main.htm里面都是什么

 

四十五、用frameset的好處

可以使用母版頁。母版頁就是把公共的元素給獨立出來。上面和左面都用母版頁來做。那么,我在做后台管理系統的時候為什么沒用母版頁用的是frameset呢?用母版頁一點就刷新,體驗性不是特別的好。

 

四十六、frameset布局

前台(大眾用戶看的)頁面的布局的時候,一般都用母版頁來做,為什么這又不用frameset呢?frameset不利於SEO的優化,搜索引擎都有蜘蛛爬蟲,這些蜘蛛不喜歡頁面是frameset布局的。frameset放的是不同的頁面,蜘蛛所喜歡頁面就是一個頁面。對於網站的后台(給管理員看的)就無所謂了。

接下來我們再回顧一下frameset的基本用法,

 

四十七、主頁面

不需要用body了,因為body里面放的是網頁的主體,只管分割,具體的內容顯示交給其它的頁面了。rows橫向分割,iframe是內嵌框架,*剩下的高度或寬度,rows和cols不能同時使用。在left.html中設定target

 

四十八、設定left.html中的target屬性

在使用frameset的時候,最好給它定死。noresize這個屬性就是干這個事兒的。

下面我們看下菜單表的設計:

 

四十九、菜單設計一frameset

下面我們就看下怎么把菜單給取出來,

 

五十、干掉這條語句

 

五十一、給TreeView起個名字

菜單存在數據表里面,下一步要考慮菜單這個數據表它應該怎么設計。通過觀察我們發現菜單是個樹狀結構,數據表要體現出這種主次關系。那么數據表怎么設計呢?通過父id體現這種主次關系。

 

五十二、數據表設計

那么我們這里不寫ParentID行不行呢?做成兩個表行不行呢?不行的,子菜單下面可能還有子菜單。所以,以后設計這種樹狀結構的時候,要增加一個父節點。

 

五十三、這樣設計是不行的

下面我們就看下怎么取數據。

                    

五十四、IsPostBack屬性

這個判斷是我們在服務端經常用到的判斷,下面我們再來說一下IsPostBack的用法。曾經是個面試題呦!

IsPostBack這個屬性的值是個bool類型的,那么他在什么情況下為true,什么情況下為false呢?

當是一個get請求時,該屬性的值為false。

如果是一個post請求時,該屬性的值為true。

什么時候發get請求呢?用戶在地址欄里面輸入網址,點個超鏈接。

那么什么時候發post請求呢?

提交表單submit的時候。

那么在這個地方,加這個判斷的意義是什么呢?

獲取所有的菜單項,查詢數據庫,當用戶第一次訪問這個頁面的時候,我們把數據從數據庫里面取出來。加載到TreeView上,頁面上有個submit或其它的提交按鈕的話,一點按鈕,發出post請求。導致頁面揮發、刷新。這時還會再走下Page_Load方法,如果不加if(!IsPostBack)判斷,又查詢數據庫了。加上這層判斷就不用查詢數據庫了,因為IsPostBack屬性為true,又加了個非。不成立就不執行下面的代碼了。

繼續往下走,為什么點擊按鈕導致頁面刷新,為什么不用查數據庫但是數據沒有丟呢?因為VIEWSTATE。

 

五十五、viewstate

畫圖演示這個問題,

 

五十六、_ _VIEWSTATE出現的場景

那么IsPostBack這個屬性,它怎么知道用戶發的是get請求還是一個post請求呢?

根據的是請求報文,如果是get請求,請求報文里面只有請求頭。如果是post請求還有請求體。

如果發出的是post請求,這時候會把_ _VIEWSTATE發到服務端,服務端一看有隱藏域過來,IsPostBack為true。

 

五十七、禁用隱藏域

當我們禁用隱藏域以后,_ _VIEWSTATE還有,但是它的value很少了。那么,我們想完完整整的干掉隱藏域的話,應該怎么辦呢?

 

五十八、徹底干掉隱藏域

  但是,如果把它去掉了,服務端控件就沒辦法使用了,這樣就回到了純HTML的時代。

所以說,_ _VIEWSTATE這個東西讓人用起來很方便,但是它返回的這坨代碼很不爽。瀏覽器要加載這些東西,讓瀏覽器變得很慢,卡住了一樣。一般情況下,我們把隱藏域禁用掉。如果禁用掉的話,每次都要查數據庫了。就不能加剛才的if(!IsPostBack)判斷了。大家會問,如果我每次查詢數據庫的話也很慢,其實,在這個地方有外國專家寫過博客,連數據庫的時間比加載_ _VIEWSTATE的時間要短。一般情況下我們要把_ _VIEWSTATE禁用掉。但是我們現在做的是后台,就無所謂了。要是我們后面做圖書列表的話,就沒必要用_ _VIEWSTATE了。又不想每次查詢數據,就只能啟用緩存了。

 

下面我們就寫下GetTreeData()

 

五十九、數據訪問層代碼

 

六十、業務邏輯層代碼

 

六十一、UI層代碼

接下來我們考慮下權限問題,我們獲取用戶的權限編號和菜單的權限編號進行一個對比.

                       

六十二、權限編號的由來

首先應獲取下用戶所具有的權限編號,

 

六十三、分析哪兩張表關聯好寫sql語句

分析結果:角色權限關系表dbo.Accounts_RolePermissions

用戶角色關系表dbo.Accounts_UserRoles

通過RoleID關聯起來,得到權限編號了。

 

六十四、寫好DAL.Account_UserService

 

六十五、寫好BLL.Account_UserManager

然后再回到left.aspx.cs頁面

 

六十六、登錄的時候存到Session里面

 

六十七、權限UI層

最后,我們來看下退出的問題。

 

六十八、放個退出按鈕

 

六十九、切換到設計模式

       

七十、退出代碼

       這塊出問題了,我們用的是frameset,跳轉的時候只跳出上面這塊。

 

七十一、這樣寫退出

target的其它選項自己去查,比較簡單,不再這里說了。

再加個Loginout.aspx頁面。其實退出頁做個一般處理程序比較的好。

 

七十二、新建退出頁

 

七十三、頁面報錯

 

七十四、報錯的原因

關鍵就是target屬性,今天我們的文章當中就提到了兩次。

作者近期文章列表:

C#中級進階教程(完全免費,獻給代碼愛好者的最好禮物。注:本作者分享自己精心整理的C#中級進階教程,無任何商業目的。希望與更多的代碼愛好者交流心得,也請高手多多指點!!!)
三層及其它內容 遞歸
三層(一)
三層相關案例(及常見的錯誤)
三層實例(內涵Sql CRUD)
手寫代碼生成器
SQL數據庫 ADO.net 數據庫的應用圖解一
數據庫的應用詳解二
ADO.NET(內涵效率問題)
ADO.NET實例教學一
ADO.NET(內含存儲過程講解)
面向過程,面向對象中高級 面向過程,面向對象的深入理解一
面向過程,面向對象的深入理解二
面向對象的深入理解三
無處不在的XML
winform基礎 Winform基礎
winform中常用的控件
面向過程 三種循環的比較
C#中的方法(上)
我們常見的數組
面向對象 思想的轉變
C#中超級好用的類
C#中析構函數和命名空間的妙用
C#中超級好用的字符串
C#中如何快速處理字符串
值類型和引用類型及其它
ArrayList和HashTable妙用一
ArrayList和HashTable妙用二
文件管理File類
多態
C#中其它一些問題的小節
GDI+ 這些年我收集的GDI+代碼
這些年我收集的GDI+代碼2
HTML概述以及CSS 你不能忽視的HTML語言
你不能忽視的HTML語言2精編篇
你不能忽視的HTML語言3
CSS基本相關內容--中秋特別奉獻
CSS基本相關內容2
JavaScript基礎 JavaScript基礎一
javascript基礎二JavaScript DOM編程
jQuery jQuery(內涵: jquery選擇器)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM