【無私分享:從入門到精通ASP.NET MVC】從0開始,一塊兒搭框架、作項目(5.1) 登陸功能的實現,開始接觸Spring IOC、DI

索引html

【無私分享:從入門到精通ASP.NET MVC】從0開始,一塊兒搭框架、作項目 目錄索引

簡述算法

今天咱們作登陸,今天的東西比較多,用到了Spring的IOC和DI、接口的使用、驗證等,但願你們多多討論spring

項目準備數據庫

咱們用的工具是:VS 2013 + SqlServer 2012 + IIS7.5框架

但願你們對ASP.NET MVC有一個初步的理解,理論性的東西咱們不作過多解釋,有些地方不理解也不要緊,會用就好了,用的多了,用的久了,天然就理解了。less

項目開始ide

1、首先簡單介紹一下IOC和DI工具

Ioc:Inversion of Control,即「控制反轉」,他不是什麼新的技術,而是一種設計思想。post

一般咱們是這麼理解,咱們通常的設計思想是在對象內部直接控制,而IOC是將設計好的對象交給容器控制,而不是傳統的在對象內部直接控制。網站

打個比方:咱們租房子,在咱們和房主之間插入了一箇中間人(房介),咱們只須要跟房介提出咱們的要求,好比房子要三室一廳、臥室向陽、房東是女的(*^_^* )、樓層不要過低、遮光不要太長等等等等,而後房介就會按照咱們的要求給咱們提供一個房產信息,咱們滿意就跟租賃、入住,若是咱們不滿意(拋出異常),房介就會幫咱們作後續處理。整個過程再也不是由咱們控制,而是由房介這麼一個容器去控制。全部的類都會在spring容器中登記,告訴spring你是個什麼東西,你須要什麼東西,而後spring會在系統運行到適當的時候,把你要的東西主動給你,同時也把你交給其餘須要你的東西。全部的類的建立、銷燬都由 spring來控制,也就是說控制對象生存週期的再也不是引用它的對象,而是spring。對於某個具體的對象而言,之前是它控制其餘對象,如今是全部對象都被spring控制,因此這叫控制反轉。

DI:IOC的一個重點是在系統運行中,動態的向某個對象提供它所須要的其餘對象。這一點是經過DI(Dependency Injection,依賴注入)來實現的。好比對象A須要操做數據庫,之前咱們老是要在A中本身編寫代碼來得到一個Connection對象,有了 spring咱們就只須要告訴spring,A中須要一個Connection,至於這個Connection怎麼構造,什麼時候構造,A不須要知道。在系統運行時,spring會在適當的時候製造一個Connection,而後像打針同樣,注射到A當中,這樣就完成了對各個對象之間關係的控制。A須要依賴 Connection才能正常運行,而這個Connection是由spring注入到A中的,依賴注入的名字就這麼來的。那麼DI是如何實現的呢? 有一個重要特徵是反射(reflection),它容許程序在運行的時候動態的生成對象、執行對象的方法、改變對象的屬性,spring就是經過反射來實現注入的。

若是你還不理解,那麼請移步百度~~

 

2、理論性的東西,經過代碼的實現更容易理解一些,如今咱們來作用戶管理的接口

咱們首先在Service類庫下面建立兩個文件夾 IService(存放接口)、ServiceImp(實現類),而且在這兩個文件夾下面再分別建兩個文件夾ComManage和SysManage,用戶區分管理咱們的接口和實現類

 

 

咱們建立系統管理用戶SYS_USER的接口:右擊IService/SysManage→添加→新建項→接口  咱們叫作IUserManage

 

SysManage只是咱們爲了區分管理咱們的接口文件,咱們修改一下命名空間,讓他們統一在Service.IService空間下,而且咱們繼承基礎數據操做接口 IRepository

 

咱們添加接口方法:驗證登陸、判斷是否爲管理員、根據用戶ID獲取用戶名

 

代碼:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Service.IService
 8 {
 9     /// <summary>
10     /// Service層基本用戶信息接口
11     /// add yuangang by 2016-05-12
12     /// </summary>
13     public interface IUserManage:IRepository<Domain.SYS_USER>
14     {
15        /// <summary>
16         /// 管理用戶登陸驗證,並返回用戶信息與權限集合
17        /// </summary>
18        /// <param name="username">用戶帳號</param>
19        /// <param name="password">用戶密碼</param>
20        /// <returns></returns>
21         Domain.SYS_USER UserLogin(string useraccount, string password);
22        /// <summary>
23         /// 是否超級管理員
24        /// </summary>
25        /// <param name="userId">用戶ID</param>
26        /// <returns></returns>
27         bool IsAdmin(int userId);
28         /// <summary>
29         /// 根據用戶ID獲取用戶名,不存在返回空
30         /// </summary>
31         /// <param name="userId">用戶ID</param>
32         /// <returns></returns>
33         string GetUserName(int userId);
34     }
35 }
View Code

 

 

 咱們建立用戶接口的實現類:右擊ServiceImp/SysManage→添加→類→  咱們叫作UserManage

 

一樣,咱們修改一下命名空間,讓他們統一在Service.ServiceImp空間下,而且咱們繼承基礎數據操做類 RepositoryBase和他的接口IUserManage

 

咱們分別實現接口的方法:

 

代碼:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace Service.ServiceImp
 8 {
 9     public class UserManage:RepositoryBase<Domain.SYS_USER>,IService.IUserManage
10     {
11         /// <summary>
12         /// 管理用戶登陸驗證
13         /// add yuangang by 2016-05-12
14         /// </summary>
15         /// <param name="useraccount">用戶名</param>
16         /// <param name="password">加密密碼(AES)</param>
17         /// <returns></returns>
18         public Domain.SYS_USER UserLogin(string useraccount, string password)
19         {
20             var entity = this.Get(p => p.ACCOUNT == useraccount);
21             
22             //由於咱們用的是AES的動態加密算法,也就是沒有統一的密鑰,那麼兩次一樣字符串的加密結果是不同的,因此這裏要經過解密來匹配
23             //而不能經過再次加密輸入的密碼來匹配
24             if (entity != null && new Common.CryptHelper.AESCrypt().Decrypt(entity.PASSWORD) == password)
25             {
26                 return entity;
27             }
28             return null;
29         }
30 
31         /// <summary>
32         /// 是否超級管理員
33         /// </summary>
34         public bool IsAdmin(int userId)
35         {      
36             //這裏咱們尚未作用戶角色 因此先返回個True,後面咱們作角色的時候再回來修改
37             return true;
38         }
39 
40         /// <summary>
41         /// 根據用戶ID獲取用戶名
42         /// </summary>
43         /// <param name="Id">用戶ID</param>
44         /// <returns></returns>
45         public string GetUserName(int Id)
46         {
47             var query = this.LoadAll(c => c.ID == Id);
48             if (query == null || !query.Any())
49             {
50                 return "";
51             }
52             return query.First().NAME;
53         }
54     }
55 }
View Code

 

重要:在這說明一下,由於以前我一直用的DES加密算法,後來改爲了AES動態加密,可是Common類庫下面的CryptHelper/DESCrypt一直沒有改過來,這給不少細心的朋友形成了困擾,命名方法體就是 【C#公共幫助類】給你們分享一些加密算法 (DES、HashCode、RSA、AES等) 裏的AES,這裏怎麼是DES呢?首先,我表示抱歉,在這呢,一勞永逸,我修改了Common/CryptHelper/DESCrypt,目前咱們用到的地方只有兩個,一個就是咱們上面代碼中的 UserLogin,另外一個是Common/Utils.cs 第1611行, 得到當前完整Url地址。你們修改一下。

 

我從新把修改後的代碼貼一下:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.IO;
  4 using System.Linq;
  5 using System.Security.Cryptography;
  6 using System.Text;
  7 
  8 namespace Common.CryptHelper
  9 {
 10     public class AESCrypt
 11     {
 12        public const string RET_ERROR = "x07x07x07x07x07";
 13        private byte[] _IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
 14        private byte[] _Key = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
 15        private const string CRYPTO_KEY = "WKMVCYUANGANG";
 16        private int CRYPTO_KEY_LENGTH = 32;
 17   
 18        private AesCryptoServiceProvider m_aesCryptoServiceProvider;
 19        private string m_message;
 20        public string Message
 21        {
 22            get { return m_message; }
 23            set { m_message = value; }
 24        }
 25        private bool m_containKey;
 26        /// <summary>
 27        /// True:密文中包含密鑰
 28        /// False:密文中不包含密鑰
 29        /// </summary>
 30        public bool ContainKey
 31        {
 32            get { return m_containKey; }
 33            set { m_containKey = value; }
 34        }
 35        public AESCrypt()
 36        {
 37            m_aesCryptoServiceProvider = new AesCryptoServiceProvider();
 38            m_containKey = true;
 39            m_message = string.Empty;
 40        }
 41        public AESCrypt(bool containKey)
 42            : this()
 43        {
 44            m_containKey = containKey;
 45        }
 46        private string Encrypt(string s_crypto, byte[] key)
 47        {
 48            string s_encryped = string.Empty;
 49            byte[] crypto, encrypted;
 50            ICryptoTransform ct;
 51   
 52            try
 53            {
 54                crypto = string2Byte(s_crypto);
 55                m_aesCryptoServiceProvider.Key = key;
 56                m_aesCryptoServiceProvider.IV = _IV;
 57                ct = m_aesCryptoServiceProvider.CreateEncryptor();
 58                encrypted = ct.TransformFinalBlock(crypto, 0, crypto.Length);
 59                if (m_containKey)
 60                {
 61                    s_encryped += byte2HexString(key);
 62                }
 63                s_encryped += byte2HexString(encrypted);
 64                return s_encryped;
 65            }
 66            catch (Exception ex)
 67            {
 68                m_message = ex.ToString();
 69                return RET_ERROR;
 70            }
 71        }
 72        /// <summary>
 73        /// 指定密鑰對明文進行AES加密
 74        /// </summary>
 75        /// <param name="s_crypto">明文</param>
 76        /// <param name="s_key">加密密鑰</param>
 77        /// <returns></returns>
 78        public string Encrypt(string s_crypto, string s_key)
 79        {
 80            byte[] key = new byte[CRYPTO_KEY_LENGTH];
 81   
 82            byte[] temp = string2Byte(s_key);
 83            if (temp.Length > key.Length)
 84            {
 85                m_message = "Key too long,need less than 32 Bytes key.";
 86                return RET_ERROR;
 87            }
 88            key = string2Byte(s_key.PadRight(key.Length));
 89            return Encrypt(s_crypto, key);
 90        }
 91        /// <summary>
 92        /// 動態生成密鑰,並對明文進行AES加密
 93        /// </summary>
 94        /// <param name="s_crypto">明文</param>
 95        /// <returns></returns>
 96        public string Encrypt(string s_crypto)
 97        {
 98            byte[] key = new byte[CRYPTO_KEY_LENGTH];
 99   
100            m_aesCryptoServiceProvider.GenerateKey();
101            key = m_aesCryptoServiceProvider.Key;
102            return Encrypt(s_crypto, key);
103        }
104   
105        private string Decrypt(string s_encrypted, byte[] key)
106        {
107            string s_decrypted = string.Empty;
108            byte[] encrypted, decrypted;
109            ICryptoTransform ct;
110   
111            try
112            {
113                encrypted = hexString2Byte(s_encrypted);
114                m_aesCryptoServiceProvider.Key = key;
115                m_aesCryptoServiceProvider.IV = _IV;
116                ct = m_aesCryptoServiceProvider.CreateDecryptor();
117                decrypted = ct.TransformFinalBlock(encrypted, 0, encrypted.Length);
118                s_decrypted += byte2String(decrypted);
119                return s_decrypted;
120            }
121            catch (Exception ex)
122            {
123                m_message = ex.ToString();
124                m_message = "Decrypt fail.";
125                return RET_ERROR;
126            }
127        }
128        /// <summary>
129        /// 從密文中解析出密鑰,並對密文進行解密
130        /// </summary>
131        /// <param name="s_encrypted">密文</param>
132        /// <returns></returns>
133        public string Decrypt(string s_encrypted)
134        {
135            string s_key = string.Empty;
136            byte[] key = new byte[CRYPTO_KEY_LENGTH];
137   
138            if (s_encrypted.Length <= CRYPTO_KEY_LENGTH * 2)
139            {
140                m_message = "Encrypted string invalid.";
141                return RET_ERROR;
142            }
143            if (m_containKey)
144            {
145                s_key = s_encrypted.Substring(0, CRYPTO_KEY_LENGTH * 2);
146                s_encrypted = s_encrypted.Substring(CRYPTO_KEY_LENGTH * 2);
147            }
148            key = hexString2Byte(s_key);
149            return Decrypt(s_encrypted, key);
150        }
151        /// <summary>
152        /// 指定密鑰,並對密文進行解密
153        /// </summary>
154        /// <param name="s_encrypted">密文</param>
155        /// <param name="s_key">密鑰</param>
156        /// <returns></returns>
157        public string Decrypt(string s_encrypted, string s_key)
158        {
159            byte[] key = new byte[CRYPTO_KEY_LENGTH];
160   
161            byte[] temp = string2Byte(s_key);
162            if (temp.Length > key.Length)
163            {
164                m_message = "Key invalid.too long,need less than 32 Bytes";
165                return RET_ERROR;
166            }
167            key = string2Byte(s_key.PadRight(key.Length));
168            if (m_containKey)
169            {
170                s_encrypted = s_encrypted.Substring(CRYPTO_KEY_LENGTH * 2);
171            }
172            return Decrypt(s_encrypted, key);
173        }
174 
175        #region 私有方法
176        private string byte2HexString(byte[] bytes)
177        {
178            StringBuilder sb = new StringBuilder();
179            foreach (byte b in bytes)
180            {
181                sb.AppendFormat("{0:X2}", b);
182            }
183            return sb.ToString();
184        }
185        private byte[] hexString2Byte(string hex)
186        {
187            int len = hex.Length / 2;
188            byte[] bytes = new byte[len];
189            for (int i = 0; i < len; i++)
190            {
191                bytes[i] = (byte)(Convert.ToInt32(hex.Substring(i * 2, 2), 16));
192            }
193            return bytes;
194        }
195        private byte[] string2Byte(string str)
196        {
197            return Encoding.UTF8.GetBytes(str);
198        }
199        private string byte2String(byte[] bytes)
200        {
201            return Encoding.UTF8.GetString(bytes);
202        }
203        #endregion
204 
205     
206     }
207 }
View Code

 這是一個小小的插曲~~~

 

咱們繼續,咱們在Service類庫下面新建一個文件夾Config用於存放注入文件,咱們在這個文件夾下面新建兩個XML文件ComService.xml和Service.xml

咱們把這兩個文件屬性的生成操做修改成嵌入的資源:分別右擊這兩個XML文件→屬性→生成操做→嵌入的資源

 

 

 

而後咱們移步操做WebPage,咱們新建個文件夾Config,而後新建3個XML文件:

ComControllers.xml:後臺管理Com控制器

Controllers.xml:後臺管理Sys控制器

IndexControllers.xml:網站前臺控制器

分別更改3個文件屬性的生成操做修改成嵌入的資源(同上)

 

 

下一步咱們修改一下WebPage的 Web.Config 聲明一下Spring容器和配置指向,注意他們的位置

 

代碼:

Spring聲明容器

1 <sectionGroup name="spring">
2       <!--Spring聲明容器-->
3       <section name="context" type="Spring.Context.Support.MvcContextHandler, Spring.Web.Mvc5" />
4       <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
5     </sectionGroup>
View Code

Spring配置指向

 1 <!--Spring配置指向-->
 2   <spring>
 3     <context>
 4       <!--WebPage-->
 5       <resource uri="assembly://WebPage/WebPage.Config/IndexControllers.xml" />
 6       <resource uri="assembly://WebPage/WebPage.Config/Controllers.xml" />
 7       <resource uri="assembly://WebPage/WebPage.Config/ComControllers.xml" />
 8       <!--Service-->
 9       <resource uri="assembly://Service/Service.Config/Service.xml" />
10       <resource uri="assembly://Service/Service.Config/ComService.xml" />
11     </context>
12   </spring>
View Code

 

因爲你們是比較着急的,時間呢又是那麼的不經用,因此這一篇文章,咱們分爲幾部分來寫,今天的第一部分,咱們先到這,下一部分,我會抓緊寫~~~

 

原創文章 轉載請尊重勞動成果 http://yuangang.cnblogs.com

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息