許多 Web 應用程序要求在用戶登錄之后才授予其對受限制內容的訪問權限。
在某些應用程序中,即使是登錄的用戶,也會限制他們可以查看的內容或可以編輯的字段。
要限制對 ASP.NET MVC 視圖的訪問,您可以限制對呈現視圖的操作方法的訪問。
為此,MVC 框架提供 AuthorizeAttribute 類。
MVC的一些特性,如下:
BindAttribute(限制實體屬性)
RemoteAttribute(遠程驗證,需要頁面使用jquery.validate.js和jquery.validate.unobtrusive.js)
HandleErrorAttribute(根據異常類型直接跳轉到相應的錯誤頁面)
HiddenInputAttribute(在Model中直接控制頁面輸入框顯示,用處不大)
BindAttribute
使用BindAttribute的目的是限制用戶在提交form表單時使用合適且正確的值。當我們提交一個表單時,就會檢查每一個實體上綁定的特性。
假設我們已經有下面一個Employee實體類:
-
public class Employee { public string Name { get; set; } public string Email { get; set; } public string Address { get; set; } public string PhoneNo { get; set; } }
建立一個EmployeeController,里面添加兩個Action:
-
[HttpGet] public ActionResult EmployeeRegister() { return View(); } [HttpPost] public ActionResult EmployeeRegister(Employee emp) { return View(); }
給第一個Action建立視圖,並且發送post表單數據過來。
這樣在第二個Action中,就會接收到參數,自動轉成Employee類,包含4個屬性
現在如果我們只想提交Email,Name和PhoneNo,而我們不想提交Address,這時我們可以在實體類上添加如下特性:
[Bind(Exclude="Address")] public class Employee { public string Name { get; set; } public string Email { get; set; } public string Address { get; set; } public string PhoneNo { get; set; } }
此時其他三個屬性正常,Address變成了null.
我們也可以將BindAttribute直接用在Action的參數中,像下面這樣:
[HttpPost] public ActionResult EmployeeRegister([Bind(Exclude = "Address")]Employee emp) { return View(); }
注意:BindAttribute位於System.Web.Mvc命名空間下
Remote Attribute
假設我們有一個注冊表單,里面有郵箱文本框,當輸入郵箱后,我們想檢查輸入的郵箱是否在數據庫中已經存在,如果存在,則不提交表單,這時我們可以使用RemoteAttribute,通過RemoteAttribute,我們可以在進入Action前自動先進行一些服務端驗證。
我們可以在下面的例子中使用RemoteAttribute:
-
public class Employee { public string Name { get; set; } [Remote("CheckEmail","Employee",ErrorMessage="Email is already exist")] public string Email { get; set; } public string Address { get; set; } public string PhoneNo { get; set; } }
RemoteAttribute的第一個參數是一個Action名字,第二個是Controller名字,第三個是如果郵箱已存在后顯示給用戶看的提示信息。當我們輸入完郵箱后,CheckEmail方法將被執行並檢查郵箱是否存在。
-
public JsonResult CheckEmail(string Email) { //Check here in database if it exist in database return true else false. return Json(false, JsonRequestBehavior.AllowGet); }
此時頁面上郵箱的輸入框一旦發生onchange,就會自動發送異步請求到CheckEmail方法,頁面可以使用如下代碼:
@Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
來配合處理
個人認為,該特性基本沒什么用
HandleError Attribute
我們已經有很多方法在MVC中處理異常,比如用try catch,或者使用Filter,或者通過第三方庫比如elmah。但是MVC也提供了一個HandleErrorAttribute去處理異常,如下:
-
[HandleError()] public ActionResult CheckError() { int a = 10; int b = 0; int k = a / b; return View(); }
在web.config文件中,我們在<system.web>中添加如下兩行:
-
<customErrors mode ="On" defaultRedirect ="Error.cshtml"> </customErrors>
在shared文件夾下創建一個視圖Error.cshtml,然后運行程序,如果運行上面的CheckError()方法,剛創建的Error.cshtml將會顯示出來。
還可以根據異常類型的不同跳轉到不同的錯誤界面。
-
[HandleError(ExceptionType=typeof(DivideByZeroException),View="嘗試除以0的View")] [HandleError(ExceptionType = typeof(NullReferenceException), View = "引用null對象的View")] public ActionResult CheckError() { int a = 10; int b = 0; int k = a / b; return View(); }
可以重寫該特性進行錯誤日志記錄!調用方式有兩種:1、global全局注冊,2、加在控制器或Action上
使用 handleError attribute 有以下局限:
1. 不支持exception記錄
2. 無法捕捉到500之外的http exception
3. controller之外拋出的異常無法處理
4. ajax調用出現exception時,會將錯誤頁面內容返回
HiddenInput Attribute
如果我們想對用戶隱藏一些實體字段,我們可以使用HiddenInput特性。
-
public class Employee { [HiddenInput(DisplayValue=false)] public string Name { get; set; } [Remote("CheckEmail","Employee",ErrorMessage="Email is already exist")] public string Email { get; set; } public string Address { get; set; } public string PhoneNo { get; set; } }
這樣頁面上Name的輸入框將不會出現,必須使用如下代碼才可實現控制效果:
@Html.EditorFor(model => model.Name, new {})
強類型控制,Name和頁面頭部引用@model xxx.Models.Employee必須保持一致
個人認為,用處不大