Asp.net mvc 知多少(八)

本系列主要翻譯自《ASP.NET MVC Interview Questions and Answers 》- By Shailendra Chauhan,想看英文原版的可訪問(wèn)http://www.dotnettricks.com/free-ebooks自行下載搏讶。該書(shū)主要分為兩部分预鬓,ASP.NET MVC 5乌妒、ASP.NET WEB API2绣的。本書(shū)最大的特點(diǎn)是以面試問(wèn)答的形式進(jìn)行展開(kāi)高氮。通讀此書(shū)彼哼,會(huì)幫助你對(duì)ASP.NET MVC有更深層次的理解迹淌。
由于個(gè)人技術(shù)水平和英文水平也是有限的河绽,因此錯(cuò)誤在所難免己单,希望大家多多留言指正。
系列導(dǎo)航
Asp.net mvc 知多少(一)
Asp.net mvc 知多少(二)
Asp.net mvc 知多少(三)
Asp.net mvc 知多少(四)
Asp.net mvc 知多少(五)
Asp.net mvc 知多少(六)
Asp.net mvc 知多少(七)
Asp.net mvc 知多少(八)
Asp.net mvc 知多少(九)
Asp.net mvc 知多少(十)

本節(jié)主要講解過(guò)濾器

Q78. 介紹下ASP.NET MVC中的 Filters(過(guò)濾器) 和 Attributes(特性)?
Ans. ASP.NET MVC 提供了一種簡(jiǎn)單的方式在action執(zhí)行之前或之后注入一段代碼或邏輯葵姥,它就是ASP.NET MVC attributes荷鼠,通過(guò)在Controller或者Action上使用Attributes來(lái)修飾即可±菩遥可以自定義過(guò)濾器或特性通過(guò)實(shí)現(xiàn)ASP.NET
MVC filter 接口或繼承并重載ASP.NET MVC filter attribute類允乐。
通常,過(guò)濾器被用來(lái)執(zhí)行以下常見(jiàn)的功能點(diǎn):

  1. Custom Authentication(自定義認(rèn)證)
  2. Custom Authorization (User based or Role based)(自定義授權(quán)-基于用戶或角色)
  3. Error handling or logging(異常處理或記錄日志)
  4. User Activity Logging(用戶活動(dòng)日志)
  5. Data Caching(數(shù)據(jù)緩存)
  6. Data Compression(數(shù)據(jù)壓縮)

Q79. 介紹下ASP.NET MVC中幾種不同的Filters(過(guò)濾器) ?
Ans. 主要有以下五種類型Filters:
Authentication Filters(認(rèn)證過(guò)濾器) - 該過(guò)濾器是從ASP.NET MVC5中引入的削咆。IAuthenticationFilter接口是用來(lái)創(chuàng)建自定義認(rèn)證過(guò)濾器牍疏。IAuthenticationFilter定義如下:

public interface IAuthenticationFilter
{
 void OnAuthentication(AuthenticationContext filterContext);
 void OnAuthenticationChallenge(AuthenticationChallengeContext
filterContext);
}

通過(guò)實(shí)現(xiàn)IAuthenticationFilter接口,即可實(shí)現(xiàn)自定義的認(rèn)證過(guò)濾特性拨齐。

public class CustomAuthenticationFilterAttribute : FilterAttribute,
IAuthenticationFilter
{
 public void OnAuthentication(AuthenticationContext filterContext)
 {
 filterContext.HttpContext.Response.Write("Authentication
Filter<br/>");
 }
 //Runs after the OnAuthentication method
 public void OnAuthenticationChallenge(AuthenticationChallengeContext
filterContext)
 {
 //TODO: Additional tasks on the request
 }
}

Authorization Filters(授權(quán)過(guò)濾器) - ASP.NET MVC的授權(quán)過(guò)濾器實(shí)現(xiàn)了IAuthorizationFilter接口鳞陨。

public interface IAuthorizationFilter
{
 void OnAuthorization(AuthorizationContext filterContext);
}

AuthorizeAttribute提供了以下可重載的方法:

public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter
{
 protected virtual bool AuthorizeCore(HttpContextBase httpContext);
 protected virtual void HandleUnauthorizedRequest(AuthorizationContext
filterContext);
public virtual void OnAuthorization(AuthorizationContext filterContext);
 protected virtual HttpValidationStatus
OnCacheAuthorization(HttpContextBase httpContext);
}

所以,我們可以通過(guò)實(shí)現(xiàn)IAuthorizationFilter接口或者繼承AuthorizeAttribute類然后重載虛方法來(lái)創(chuàng)建自定義的授權(quán)過(guò)濾器瞻惋。

Action Filters(操作過(guò)濾器) - Action filters 在action執(zhí)行之前和之后執(zhí)行厦滤。IActionFilter接口提供了OnActionExecutingOnActionExecuted 方法分別對(duì)應(yīng)action之前和action之后執(zhí)行。

public interface IActionFilter
{
 void OnActionExecuting(ActionExecutingContext filterContext);
 void OnActionExecuted(ActionExecutedContext filterContext);
}

** Result Filters(結(jié)果過(guò)濾器)** - Result filters在為action生成結(jié)果之前和和之后執(zhí)行歼狼。返回的結(jié)果可以是 ViewResult掏导、PartialViewResult、RedirectToRouteResult羽峰、RedirectResult趟咆、ContentResult、JsonResult梅屉、FileResult 和 EmptyResult 值纱,它們均繼承自 ActionResult 類。Result filters 在Action Filters之后調(diào)用坯汤。
IResultFilter接口提供了OnResultExecutingOnResultExecuted 方法分別對(duì)應(yīng)生成結(jié)果之前和之后執(zhí)行虐唠。

public interface IResultFilter
{
 void OnResultExecuted(ResultExecutedContext filterContext);
 void OnResultExecuting(ResultExecutingContext filterContext);
}

** Exception Filters (異常過(guò)濾器)** - Exception filters在action或者過(guò)濾器執(zhí)行期間出現(xiàn)異常時(shí)執(zhí)行。IExceptionFilter接口提供了OnException方法來(lái)處理異常惰聂。

public interface IExceptionFilter
{
 void OnException(ExceptionContext filterContext);
}

HandleErrorAttribute類實(shí)現(xiàn)了IExceptionFilter接口凿滤。
當(dāng)HandleError接收到異常,它會(huì)直接返回ASP.NET MVC Views/Shared 文件夾下的Error視圖庶近。


Q80. ASP.NET MVC的 Exception filters(異常過(guò)濾)何時(shí)執(zhí)行?
Ans. Exception filters 在ASP.NET MVC pipeline(管道)執(zhí)行期間有一個(gè)未處理的異常拋出時(shí)被執(zhí)行。


Q81. ASP.NET MVC中filters(過(guò)濾器)的執(zhí)行順序是眷蚓?
Ans. 所有的 ASP.NET MVC filter都是按照一定的順序執(zhí)行鼻种。 執(zhí)行順序?yàn)椋?/p>

  1. Authentication filters(認(rèn)證過(guò)濾器)
  2. Authorization filters(授權(quán)過(guò)濾器)
  3. Action filters(操作過(guò)濾器)
  4. Result filters(結(jié)果過(guò)濾器)

Q82. ASP.NET MVC中如何配置過(guò)濾器?
Ans. 我們可以配置自定義的過(guò)濾器為以下三個(gè)級(jí)別:
Global level(全局級(jí)別)
將過(guò)濾器注冊(cè)到Global.asax.cs文件的Application_Start方法中:

protected void Application_Start()
{ FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
}

Controller level(控制器級(jí)別)
通過(guò)將過(guò)濾器標(biāo)記在controller上即可沙热。

[Authorize(Roles = "Admin")]
public class AdminController : Controller
{
 //TODO:
}

Action level (操作級(jí)別)
通過(guò)將過(guò)濾器標(biāo)記在action上即可叉钥。

public class UserController : Controller
{
 [Authorize(Users = "User1,User2")]
 public ActionResult LinkLogin(string provider)
 {
 // TODO:
 return View();
 }
}

Q83. ASP.NET MVC中認(rèn)證和授權(quán)是如何工作的罢缸?
Ans. 像 ASP.NET一樣,MVC 也支持 Windows 和Forms 認(rèn)證投队》憬可以通過(guò)在Web.config中配置或自己編碼。


Q84. ASP.NET MVC中 Forms Authentication 和 Authorization(表單認(rèn)證和授權(quán))是如何工作的敷鸦?
Ans. 和 ASP.NET一樣息楔, MVC Forms authentication在IIS認(rèn)證完成之后發(fā)生“桥可以在 ASP.NET MVC應(yīng)用程序中的Web.config文件的forms節(jié)點(diǎn)進(jìn)行配置值依。
默認(rèn)的表單認(rèn)證配置如下:

<system.web>
<authentication mode="Forms">
<forms loginUrl="Login.aspx"
protection="All"
timeout="30"
name=".ASPXAUTH"
path="/"
requireSSL="false"
slidingExpiration="true"
defaultUrl="default.aspx"
cookieless="UseDeviceProfile"
enableCrossAppRedirects="false" />
</authentication>
</system.web>
表單認(rèn)證控制流程

當(dāng)SetAuthCookie()RedirectFromLoginPage()被調(diào)用時(shí)FormsAuthentication類自動(dòng)創(chuàng)建認(rèn)證Cookie。 Authentication cookie(認(rèn)證Cookie)中包含一個(gè)已經(jīng)加密和簽名的FormsAuthenticationTicket對(duì)象的字符串碟案。
可以指定cookie的名稱愿险、 版本、目錄路徑价说、生效日期辆亏、過(guò)期日期、是否永久屬性來(lái)創(chuàng)建FormsAuthenticationTicket對(duì)象 鳖目。

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "userName",
DateTime.Now,
DateTime.Now.AddMinutes(30), // value of time out property
false, // Value of IsPersistent property
String.Empty, FormsAuthentication.FormsCookiePath);

然后就可以使用FormsAuthentication類的Encrypt方法來(lái)加密ticket扮叨。
string encryptedTicket = FormsAuthentication.Encrypt(ticket);


Q85. ASP.NET MVC中如何實(shí)現(xiàn)自定義Forms Authentication and Authorization(表單認(rèn)證和授權(quán))?
Ans. 當(dāng)標(biāo)準(zhǔn)的認(rèn)證不能滿足你的需求疑苔,你就需要去修改認(rèn)證機(jī)制去創(chuàng)建自定義的認(rèn)證方案甫匹。一個(gè)用戶上下文有一個(gè)Principal,這個(gè)Principal代表用戶的身份(Identity)和角色(Role)惦费。用戶通過(guò)ta的身份進(jìn)行認(rèn)證兵迅,通過(guò)給用戶分配角色來(lái)進(jìn)行授權(quán)。

用戶上下文

ASP.NET 提供了IPrincipalIIdentity接口來(lái)表示用戶的身份和角色薪贫。這兩個(gè)接口
綁定到HttpContext對(duì)象和當(dāng)前線程恍箭。可以通過(guò)實(shí)習(xí)這兩個(gè)接口來(lái)創(chuàng)建自定義的方案瞧省。

public class CustomPrincipal : IPrincipal
{
 public IIdentity Identity { get; private set; }
 public bool IsInRole(string role)
 {
 if (roles.Any(r => role.Contains(r)))
 {
 return true;
 }
 else
{
 return false;
 }
 }
 public CustomPrincipal(string Username)
 {
 this.Identity = new GenericIdentity(Username);
 }
 public int UserId { get; set; }
 public string FirstName { get; set; }
 public string LastName { get; set; }
 public string[] roles { get; set; }
}

現(xiàn)在你就可以把CustomPrincipal對(duì)象放入thread(線程)的 CurrentPrincipal屬性和HttpContext的User屬性來(lái)完成自定義的認(rèn)證和授權(quán)流程扯夭。
如果IsAuthenticated返回true則表示用戶認(rèn)證成功。我們可以用以下兩種方式來(lái)完成對(duì)用戶的驗(yàn)證鞍匾。

  1. Thread.CurrentPrincipal.Identity.IsAuthenticated
  2. HttpContext.Current.User.Identity.IsAuthenticated

ASP.NET MVC 提供了Authorization授權(quán)過(guò)濾器來(lái)對(duì)用戶授權(quán)交洗。該過(guò)濾器可適用于action級(jí)別、控制器級(jí)別和全局級(jí)別橡淑。該過(guò)濾器基于AuthorizeAttribute特性類构拳,可以通過(guò)繼承該特性并重載OnAuthorization()方法來(lái)對(duì)授權(quán)過(guò)濾器進(jìn)行自定義。

public class CustomAuthorizeAttribute: AuthorizeAttribute {
    protected virtual CustomPrincipal CurrentUser {
        get {
            return HttpContext.Current.User as CustomPrincipal;
        }
    }
    public override void OnAuthorization(AuthorizationContext filterContext) {
        if (filterContext.HttpContext.Request.IsAuthenticated) {

            if (!String.IsNullOrEmpty(Roles)) {
                if (!CurrentUser.IsInRole(Roles)) {
                    filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {
                        controller = "Error",
                        action = "AccessDenied"
                    }));
                }
            }
            if (!String.IsNullOrEmpty(Users)) {
                if (!Users.Contains(CurrentUser.UserId.ToString())) {
                    filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {
                        controller = "Error",
                        action = "AccessDenied"
                    }));
                    // base.OnAuthorization(filterContext); //returns to login url
                }
            }
        }
    }
}

現(xiàn)在你就可以像下面這樣應(yīng)用自定義的授權(quán)過(guò)濾器在控制器級(jí)別或者action級(jí)別。

[CustomAuthorize(Roles= "Admin")]
public class AdminController : BaseController
{
 public ActionResult Index()
 {
 return View();
 }
}

Q86. ASP.NET MVC如何允許輸入html tags?
Ans. ASP.NET MVC默認(rèn)不允許用戶去提交html去避免Cross Site Scripting(CSS)攻擊 置森。
ValidateInput特性可以在action級(jí)別或controller級(jí)別啟用或禁用輸入校驗(yàn)斗埂。

[ValidateInput(false)]
public class HomeController : Controller
{
 public ActionResult AddArticle()
 {
 return View();
 }
}

ValidateInput特性對(duì)所有屬性都允許html tag輸入,但這是不安全的凫海。 如果你只是想針對(duì)部分屬性允許html輸入呛凶,可以通過(guò)為屬性添加AllowHtml 特性。

public class BlogModel
{
 [Required]
 [Display(Name = "Title")]
 public string Title { get; set; }
 [AllowHtml]
 [Required]
 [Display(Name = "Description")]
 public string Description { get; set; }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末行贪,一起剝皮案震驚了整個(gè)濱河市漾稀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瓮顽,老刑警劉巖县好,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異暖混,居然都是意外死亡缕贡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)拣播,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)晾咪,“玉大人,你說(shuō)我怎么就攤上這事贮配〉耄” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵泪勒,是天一觀的道長(zhǎng)昼蛀。 經(jīng)常有香客問(wèn)我,道長(zhǎng)圆存,這世上最難降的妖魔是什么叼旋? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮沦辙,結(jié)果婚禮上夫植,老公的妹妹穿的比我還像新娘。我一直安慰自己油讯,他們只是感情好详民,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著陌兑,像睡著了一般沈跨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上兔综,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天谒出,我揣著相機(jī)與錄音隅俘,去河邊找鬼。 笑死笤喳,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的碌宴。 我是一名探鬼主播杀狡,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼贰镣!你這毒婦竟也來(lái)了呜象?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤碑隆,失蹤者是張志新(化名)和其女友劉穎恭陡,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體上煤,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡休玩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了劫狠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拴疤。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖独泞,靈堂內(nèi)的尸體忽然破棺而出呐矾,到底是詐尸還是另有隱情,我是刑警寧澤懦砂,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布蜒犯,位于F島的核電站,受9級(jí)特大地震影響荞膘,放射性物質(zhì)發(fā)生泄漏罚随。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一衫画、第九天 我趴在偏房一處隱蔽的房頂上張望毫炉。 院中可真熱鬧,春花似錦削罩、人聲如沸瞄勾。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)进陡。三九已至,卻和暖如春微服,著一層夾襖步出監(jiān)牢的瞬間趾疚,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留糙麦,地道東北人辛孵。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像赡磅,于是被迫代替她去往敵國(guó)和親魄缚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容