離上次寫MVC文章剛好一年了
這一年裡基本上我都沒機會去使用MVC
剛好這次公司有點數所以去上了課
自己又投資自己去上保哥的MVC5課程
剛好兩邊教法不一樣有些重點也不一樣
趁著還熟著時順手向同事要了個已經快開發成的案子
當然第一次寫要上線應該很難
接下來幾天會針對實作及遇到的問題做整理
一開始我想剛學完基礎的人
基本上跟我一樣不知如何下手
隨便要個舊專案或是拿個不是很重要的案子來寫
首先應該會從會員開始吧
但千萬別從新增會員開始
因為這樣就有點難了
我是以VS2013來開發目前是RTM
1.新增一個專案 > .net版本選4.5 > 選MVC > 建好了網站 > 刪除一些不必要的原件(Controllers Views Models)裡都刪了 只留View裡的Shared
2013範本是Bootstrap 3.0,jQuery 1.10.2。
2.開發分成Code First、DB First、Model First因個人習慣DB First所以先來建資料庫,先求簡單只有三個欄位,ID、登入帳號、密碼,但有一個重點記得設PK,EF必要的就是PK,這次實做簡單登入 所以直街先手動新增一筆假一料
3.建立一個ADO.NET 實體模型資料庫 > 由資料庫產生 > 新增連接 > 依提示操作設定連線資訊 > 測試連接看能不能成功 > 完成後記得build一下
4.在Controller新增一個AccountController 在新增一個View /Account/Login.cshtml
因為在微軟內建的驗證中有一個已經幫我們做好驗正了
app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login") });5.新增一個ViewModels資料夾來存放自己定義的model 加入
using System.ComponentModel.DataAnnotations; using System.ComponentModel;定義Model
public class Login { [DisplayName("登入帳號")] [Required(ErrorMessage = "請輸入登入帳號")] [StringLength(40, ErrorMessage = "登入帳號最多20個字")] public string AccountName { get; set; } [DisplayName("登入密碼")] [Required(ErrorMessage = "請輸入登入密碼")] [StringLength(40, ErrorMessage = "密碼最多20個字")] [DataType(DataType.Password)] public string Password { get; set; } }Login的畫面
2013-10-30更新
@using (Html.BeginForm("Login", "Login", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post)) { @Html.AntiForgeryToken() @*@Html.ValidationSummary()*@登入的Action後台登入
@Html.LabelFor(model => model.AccountName, new { @class = "control-label" })@Html.TextBoxFor(model => model.AccountName, new { @class = "form-control", placeholder = "請輸入登入帳號" }) @Html.ValidationMessageFor(model => model.AccountName, null, new { @class = "help-inline" })@Html.LabelFor(model => model.Password, new { @class = "control-label" })@Html.PasswordFor(model => model.Password, new { @class = "form-control", placeholder = "請輸入登入密碼" }) @Html.ValidationMessageFor(model => model.Password, null, new { @class = "help-inline" })@TempData["Error"]}
2013-10-30更新
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Login(Login form) { if (ModelState.IsValid) { //驗證資料庫登入 //這邊請使用自行驗證摟 string Sql = " AccountName == @0 and Password == @1 and IsUsed == @2"; var query = (from u in db.Account.Where(Sql, form.AccountName, form.Password, "true") select u).ToList(); if (query.Count() != 1) { ModelState.AddModelError(string.Empty, "帳號或密碼錯誤登入失敗"); return View("Index",form); } try { query[0].LoginIP =PublicFunction.GetIpAddress(); query[0].LoginDate = DateTime.Now; db.SaveChanges(); } catch (Exception ex) { ModelState.AddModelError(string.Empty, ex.Message.ToString()); return View("Index", form); } bool isPersistent = false;//如果票證將存放於持續性 Cookie 中 (跨瀏覽器工作階段儲存),則為 true,否則為 false。 如果票證是存放於 URL 中,則忽略這個值。 string userData = "";//可放使用者自訂的內容 string mAccountID = query[0].AccountID.ToString(); //寫cookie //使用 Cookie 名稱、版本、到期日、核發日期、永續性和使用者特定的資料,初始化 FormsAuthenticationTicket 類別的新執行個體。 此 Cookie 路徑設定為在應用程式的組態檔中建立的預設值。 //使用 Cookie 名稱、版本、目錄路徑、核發日期、到期日期、永續性和使用者定義的資料,初始化 FormsAuthenticationTicket 類別的新執行個體。 FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, mAccountID,//使用者ID DateTime.Now,//核發日期 DateTime.Now.AddMinutes(1800),//到期日期 30分鐘 isPersistent,//永續性 userData,//使用者定義的資料 FormsAuthentication.FormsCookiePath); string encTicket = FormsAuthentication.Encrypt(ticket); Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket)); //HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket); //cookie.Expires = ticket.Expiration; //Response.Cookies.Add(cookie); //FormsAuthentication.RedirectFromLoginPage(strUsername, isPersistent); if (form.ReturnUrl != null) { return Redirect(form.ReturnUrl.ToString()); } else { return RedirectToAction("Index", "Admin"); } } //return RedirectToAction("Index", "Login", null); return View("Index", form); }最後再需要驗證的Class上加[Authorize] 雖然大部份程式碼都是copy來的
但也花了一下午才了解如何登入
看來還真有的學呢
2013-10-26補充 請注意Web.Config裡的設定
修改成
2013-10-30更新
在login頁多加一個returnUrl
這樣使用者登入後可直接到他需要的頁面
上面的View跟Controller都需更新
public ActionResult Index(string returnUrl) { ViewBag.ReturnUrl = returnUrl; return View(); }
2013-11-13更新
MVC5使用範本新增如果加了authentication mode="Forms"
此時自訂的驗證會不正常
修改
public override void ExecuteResult(ControllerContext context) { var properties = new AuthenticationProperties() { RedirectUri = RedirectUri }; if (UserId != null) { properties.Dictionary[XsrfKey] = UserId; } context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider); }改為
public override void ExecuteResult(ControllerContext context) { //多下列這行 context.RequestContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true; var properties = new AuthenticationProperties() { RedirectUri = RedirectUri }; if (UserId != null) { properties.Dictionary[XsrfKey] = UserId; } context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider); }參考網址
點我前往
點我前往
點我前往
點我前往
點我前往
點我前往