前言
繼上一節中實現了驗證碼http://www.cnblogs.com/aehyok/archive/2013/04/19/3030212.html,現在我們可以進行對登錄界面進行整合調試了。
正題
打開系統的首頁頁面文件,Views\Home目錄下的Index.cshtml文件。要動態加載登錄窗口,需要先設置好加載路徑,因而在onReady函數前面加入以下代碼:
Ext.Loader.setConfig({ enabled: true, paths: { 'Ext.ux': 'scripts/extjs/ux' } });
代碼中,enabled為true,表示開啟動態加載,paths對象里面定義的就是加載路徑,在這里定義了Ext擴展的加載路徑為“scripts/extjs/ux”。
接着上面的代碼下加入一個請求登錄窗口的代碼:
Ext.require('Ext.ux.Login');
這樣,Ext就會自動去加載登錄窗口了。
將原來調用alert方法的語句刪除,然后加入顯示登錄窗口的代碼:
Ext.ux.Login.show();
現在,在頁面打開首頁,將看到如下圖
單擊一下圖片,驗證碼也可刷新了。但問題是沒鼠標指針不是手型的,這得改一下,要改不難,在創建Img對象的時候,加入style配置項就可以了,它會將該配置的值作為圖片的樣式,修改后的代碼如下:
me.image = Ext.create(Ext.Img, { style: "cursor:pointer ", src: "/VerifyCode", listeners: { click: me.onRefrehImage, element: "el", scope: me } });
現在先拋開數據庫,來做個簡單驗證測試一下。首先要做的是在Models目錄創建一個名為LoginModel.cs的類文件,創建后的代碼如下:
namespace ExtMVCOne.Models { public class LoginModel { [Required] [Display(Name = "用戶名")] public string UserName { get; set; } [Required] [Display(Name = "密碼")] public string Password { get; set; } [Required] [Display(Name = "驗證碼")] public string Vcode { get; set; } } }
當然還需要引用
using System.ComponentModel.DataAnnotations;
代碼中Required特性表示字段是必須的。Display用來表示字段的中文名稱,這不是必須。
模型創建后,創建一個名稱為AccountController的控制器, 並加入對模型的引用:
using ExtMVCOne.Models;
因為需要使用JSON格式返回數據,因而要引入Json.NET。你可以通過http://json.codeplex.com/網站進行,也可以通過Nuget來查找下載Json.NET。
安裝完成后,在Account控制器類中加入Josn.NET的引用:
using Newtonsoft.Json; using Newtonsoft.Json.Linq;
引用語句的第二句允許對JSON進行Linq操作,可簡化代碼。
好了,現在可以進入編碼工作了。因為不需要Index方法,因而將其修改為Login,並將返回結果由ActionResult修改為JObject。因為方法要接收提交的模型數據,因而在方法上添加HttpPost特性,並使用LoginModel作為模型。完成后的代碼如下:
[HttpPost] public JObject Login(LoginModel model) { return View(); }
因為Ext JS需要的數據格式基本是固定的,基本都是一個JSON對象,且對象內都會包含success關鍵字,因而為了簡化這個工作,可創建一個輔助函數來生成這個返回對象。在Helper目錄添加一個名稱為MyFunction.cs的類文件,代碼如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Web.Mvc; namespace ExtMVCOne.Helper { public class MyFunction { } }
先在類中添加對Json.NET的引用。然后添加一個WriteJobjectResult的靜態方法,方法的返回值為JObject。方法的參數暫時只有一個,布爾值的success。在方法內創建一個將要返回的JObject,並為其添加一個success屬性,代碼如下:
public static JObject WriteJObjectResult(bool success) { JObject jo = new JObject { new JProperty("success",success) }; return jo; }
代碼中使用了Linq來創建JObject對象,所以不熟悉的,會感覺有點怪異。目前代碼只能返回一個關鍵字,這個在以后的進程中會陸續添加,不着急。
現在切換回AccountController控制器,引用Helper命名控件,並定義一個布爾類型的變量success,並通過剛才定義的WriteJobjectResult方法返回結果(要),代碼如下:
bool success = false; return MyFunction.WriteJObjectResult(success);
創建一個類型為JObject的errors對象來存放這些錯誤信息,代碼如下:
JObject errors = new JObject();
現在先來驗證模型是否有錯,如果有錯誤,將模型中的錯誤寫到errors對象中。因為在其它窗口提交模型數據,也需要將錯誤狀態轉換到errors對象,因而可在MyFunction中添加一個ModelStateToJObject方法來處理這個。切換到MyFunction類中,添加一個名為ModelStateToJObject的靜態方法,代碼如下:
public static void ModelStateToJObject(ModelStateDictionary ModelState, JObject errors) { foreach (var c in ModelState.Keys) { if (!ModelState.IsValidField(c)) { string errStr = ""; foreach (var err in ModelState[c].Errors) { errStr += err.ErrorMessage + "<br/>"; } errors.Add(new JProperty(c, errStr)); } } }
這里別忘了引用using System.Web.Mvc。
代碼通過遍歷ModelState中不能通過驗證的字段,將其加入到errors對象中。這里有個問題一定要注意,模型中的字段名稱必須與定義表單時的字段的name名稱一致,不然后台字段與前台字段就對應不上了。
切換會AccountController控制器完成對登錄模型的驗證代碼了,代碼如下:
if (ModelState.IsValid) { } else { MyFunction.ModelStateToJObject(ModelState,errors); }
現在要考慮怎么返回這個errors對象,解決辦法是在WriteJobjectResult方法加一個類型為JObject的對象,並添加以下代碼:
if(errors !=null && errors.HasValues) { jo.Add(new JProperty("errors",errors)); }
代碼只有在errors不為null,且有值的情況下,才寫如errors關鍵字。
切換回AccountController控制器,修改好WriteJobjectResult方法的調用參數。
現在進入驗證過程,首先要驗證的是驗證碼,因而要先取到保存在Session中的驗證碼,代碼如下:
string vcode = ""; if(Session["vcode"] != null) { vcode =Session["vcode"].ToString(); }
下面就對驗證碼進行驗證了,因為Session有可能超時丟失驗證碼,因而在驗證的時候,必須保證驗證碼不能為空字符,代碼如下:
if(vcode.Count() > 0 && vcode.ToLower() == model.Vcode.ToLower()) { } else { errors.Add("Vcode", "驗證碼錯誤"); }
使用ToLower方法可以保證驗證碼不區分大小寫。當驗證錯誤的時候,將錯誤寫入errors對象,這樣在登錄窗口就可知道是驗證碼錯誤了。
暫時不用數據庫,先使用一些默認值做測試,如用戶名為admin,密碼為123456,則表示登錄成功,代碼如下:
if(model.UserName.ToLower() == "admin" && model.Password =="123456") { success = true; } else { errors.Add("UserName", "錯誤的用戶名或密碼。"); errors.Add("Password", "錯誤的用戶名或密碼。"); }
如果用戶名和密碼錯誤,則返回針對用戶名和密碼字段返回錯誤信息。如果驗證成功,返回success為true,則表示登錄成功了。
然后對login.js登錄事件添加提示信息,登錄成功的話,彈出登錄成功的提示框,失敗的話,彈出登錄失敗的提示框。
onLogin: function () { var me = this, f = me.form.getForm(); if (f.isValid()) { f.submit({ //waitMsg: "正在登錄,請等待……", //waitTitle: "正在登錄", success: function (form, action) { Ext.Msg.alert("提示信息","登錄成功!"); //window.location.reload(); }, failure: function () { Ext.Msg.alert("提示信息", "登錄失敗!"); }, scope: me }); } }
總結
從現在來看,實例代碼已經成功了,登錄也已經實現了。但是自己還是需要很多的時間來消化和吸收,水平有限,還需要繼續努力學習。