91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ASP.NET MVC常用擴展的示例分析

發布時間:2021-08-19 14:03:50 來源:億速云 閱讀:146 作者:小新 欄目:開發技術

這篇文章給大家分享的是有關ASP.NET MVC常用擴展的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

一、過濾器(Filter)

ASP.NET MVC中的每一個請求,都會分配給對應Controller(以下簡稱“控制器”)下的特定Action(以下簡稱“方法”)處理,正常情況下直接在方法里寫代碼就可以了,但是如果想在方法執行之前或者之后處理一些邏輯,這里就需要用到過濾器。

常用的過濾器有三個:Authorize(授權過濾器),HandleError(異常過濾器),ActionFilter(自定義過濾器),對應的類分別是:AuthorizeAttribute、HandleErrorAttribute和ActionFilterAttribute,繼承這些類并重寫其中方法即可實現不同的功能。

1.Authorize授權過濾器

授權過濾器顧名思義就是授權用的,授權過濾器在方法執行之前執行,用于限制請求能不能進入這個方法,新建一個方法:

public JsonResult AuthorizeFilterTest()
{
 return Json(new ReturnModel_Common { msg = "hello world!" });
}

直接訪問得到結果:

ASP.NET MVC常用擴展的示例分析

現在假設這個AuthorizeFilterTest方法是一個后臺方法,用戶必須得有一個有效的令牌(token)才能訪問,常規做法是在AuthorizeFilterTest方法里接收并驗證token,但是這樣一旦方法多了,每個方法里都寫驗證的代碼顯然不切實際,這個時候就要用到授權過濾器:

public class TokenValidateAttribute : AuthorizeAttribute
  {
    /// <summary>
    /// 授權驗證的邏輯處理。返回true則通過授權,false則相反
    /// </summary>
    /// <param name="httpContext"></param>
    /// <returns></returns>
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
      string token = httpContext.Request["token"];
      if (string.IsNullOrEmpty(token))
      {
        return false;
      }
      else
      {
        return true;
      }
    }
  }

新建了一個繼承AuthorizeAttribute的類,并重寫了其中的AuthorizeCore方法,這段偽代碼實現的就是token有值即返回true,沒有則返回false,標注到需要授權才可以訪問的方法上面:

[TokenValidate]
public JsonResult AuthorizeFilterTest()
{
  return Json(new ReturnModel_Common { msg = "hello world!" })
}

標注TokenValidate后,AuthorizeCore方法就在AuthorizeFilterTest之前執行,如果AuthorizeCore返回true,那么授權成功執行AuthorizeFilterTest里面的代碼,否則授權失敗。不傳token:

ASP.NET MVC常用擴展的示例分析

傳token:

ASP.NET MVC常用擴展的示例分析

不傳token授權失敗時進入了MVC默認的未授權頁面。這里做下改進:不管授權是成功還是失敗都保證返回值格式一致,方便前端處理,這個時候重寫AuthorizeAttribute類里的HandleUnauthorizedRequest方法即可:

/// <summary>
/// 授權失敗處理
/// </summary>
/// <param name="filterContext"></param>
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
  base.HandleUnauthorizedRequest(filterContext);

  var json = new JsonResult();
  json.Data = new ReturnModel_Common
  {
    success = false,
    code = ReturnCode_Interface.Token過期或錯誤,
    msg = "token expired or error"
  };
  json.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
  filterContext.Result = json;
}

效果:

ASP.NET MVC常用擴展的示例分析

實戰:授權過濾器最廣泛的應用還是做權限管理系統,用戶登錄成功后服務端輸出一個加密的token,后續的請求都會帶上這個token,服務端在AuthorizeCore方法里解開token拿到用戶ID,根據用戶ID去數據庫里查是否有請求當前接口的權限,有就返回true,反之返回false。這種方式做授權,相比登錄成功給Cookie和Session的好處就是一個接口PC端、App端共同使用。

2.HandleError異常過濾器

異常過濾器是處理代碼異常的,在系統的代碼拋錯的時候執行,MVC默認已經實現了異常過濾器,并且注冊到了App_Start目錄下的FilterConfig.cs:

filters.Add(new HandleErrorAttribute());

這個生效于整個系統,任何接口或者頁面報錯都會執行MVC默認的異常處理,并返回一個默認的報錯頁面:Views/Shared/Error(程序發到服務器上報錯時才可以看到本頁面,本地調試權限高,還是可以看到具體報錯信息的)

@{
  Layout = null;
}
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta name="viewport" content="width=device-width" />
  <title>錯誤</title>
</head>
<body>
  <hgroup>
    <h2>錯誤。</h2>
    <h3>處理你的請求時出錯。</h3>
  </hgroup>
</body>
</html>

默認的異常過濾器顯然無法滿足使用需求,重寫下異常過濾器,應付項目實戰中的需求:

1)報錯可以記錄錯誤代碼所在的控制器和方法,以及報錯時的請求參數和時間;

2)返回特定格式的JSON方便前端處理。因為現在系統大部分是ajax請求,報錯了返回MVC默認的報錯頁面,前端不好處理

新建一個類LogExceptionAttribute繼承HandleErrorAttribute,并重寫內部的OnException方法:

 public override void OnException(ExceptionContext filterContext)
 {
   if (!filterContext.ExceptionHandled)
   {
     string controllerName = (string)filterContext.RouteData.Values["controller"];
     string actionName = (string)filterContext.RouteData.Values["action"];
     string param = Common.GetPostParas();
     string ip = HttpContext.Current.Request.UserHostAddress;
     LogManager.GetLogger("LogExceptionAttribute").Error("Location:{0}/{1} Param:{2}UserIP:{3} Exception:{4}", controllerName, actionName, param, ip, filterContext.Exception.Message);

     filterContext.Result = new JsonResult
     {
       Data = new ReturnModel_Common { success = false, code = ReturnCode_Interface.服務端拋錯, msg = filterContext.Exception.Message },
       JsonRequestBehavior = JsonRequestBehavior.AllowGet
     };
   }
   if (filterContext.Result is JsonResult)
     filterContext.ExceptionHandled = true;//返回結果是JsonResult,則設置異常已處理
   else
     base.OnException(filterContext);//執行基類HandleErrorAttribute的邏輯,轉向錯誤頁面
 }

異常過濾器就不像授權過濾器一樣標注在方法上面了,直接到App_Start目錄下的FilterConfig.cs注冊下,這樣所有的接口都可以生效了:

filters.Add(new LogExceptionAttribute());

異常過濾器里使用了NLog作為日志記錄工具,Nuget安裝命令:

Install-Package NLog
Install-Package NLog.Config

相比Log4net,NLog配置簡單,僅幾行代碼即可,NLog.config:

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <targets>
  <target xsi:type="File" name="f" fileName="${basedir}/log/${shortdate}.log" layout="${uppercase:${level}} ${longdate} ${message}" />
  <target xsi:type="File" name="f2" fileName="D:\log\MVCExtension\${shortdate}.log" layout="${uppercase:${level}} ${longdate} ${message}" />
 </targets>
 <rules>
  <logger name="*" minlevel="Debug" writeTo="f2" />
 </rules>
</nlog>

如果報錯,日志就記錄在D盤的log目錄下的MVCExtension目錄下,一個項目一個日志目錄,方便管理。全部配置完成,看下代碼:

public JsonResult HandleErrorFilterTest()
{
  int i = int.Parse("abc");
  return Json(new ReturnModel_Data { data = i });
}

字符串強轉成int類型,必然報錯,頁面響應:

ASP.NET MVC常用擴展的示例分析

同時日志也記錄下來了:

ASP.NET MVC常用擴展的示例分析

3.ActionFilter自定義過濾器

自定義過濾器就更加靈活了,可以精確的注入到請求前、請求中和請求后。繼承抽象類ActionFilterAttribute并重寫里面的方法即可:

public class SystemLogAttribute : ActionFilterAttribute
{
  public string Operate { get; set; }

  public override void OnActionExecuted(ActionExecutedContext filterContext)
  {
    filterContext.HttpContext.Response.Write("<br/>" + Operate + ":OnActionExecuted");
    base.OnActionExecuted(filterContext);
  }

  public override void OnActionExecuting(ActionExecutingContext filterContext)
  {
    filterContext.HttpContext.Response.Write("<br/>" + Operate + ":OnActionExecuting");
    base.OnActionExecuting(filterContext);
  }

  public override void OnResultExecuted(ResultExecutedContext filterContext)
  {
    filterContext.HttpContext.Response.Write("<br/>" + Operate + ":OnResultExecuted");
    base.OnResultExecuted(filterContext);
  }

  public override void OnResultExecuting(ResultExecutingContext filterContext)
  {
    filterContext.HttpContext.Response.Write("<br/>" + Operate + ":OnResultExecuting");
    base.OnResultExecuting(filterContext);
  }
}

這個過濾器適合做系統操作日志記錄功能:

[SystemLog(Operate = "添加用戶")]
public string CustomerFilterTest()
{
  Response.Write("<br/>Action 執行中...");
  return "<br/>Action 執行結束";
}

看下結果:

ASP.NET MVC常用擴展的示例分析

四個方法執行順序:OnActionExecuting—>OnActionExecuted—>OnResultExecuting—>OnResultExecuted,非常精確的控制了整個請求過程。

實戰中記錄日志過程是這樣的:在OnActionExecuting方法里寫一條操作日志到數據庫里,全局變量存下這條記錄的主鍵,到OnResultExecuted方法里說明請求結束了,這個時候自然知道用戶的這個操作是否成功了,根據主鍵更新下這條操作日志的是否成功字段。

二、模型綁定(ModelBinder)

先看一個普通的方法:

public ActionResult Index(Student student)
{
  return View();
}

這個方法接受的參數是一個Student對象,前端傳遞過來的參數跟Student對象里的屬性保持一直,那么就自動被綁定到這個對象里了,不需要在方法里new Student這個對象并挨個綁定屬性了,綁定的過程由MVC中的DefaultModelBinder完成的,DefaultModelBinder同時繼承了IModelBinder接口,現在就利用IModelBinder接口和DefaultModelBinder來實現更加靈活的模型綁定。

場景一、前端傳過來了一個加密的字符串token,方法里需要用token里的某些字段,那就得在方法里接收這個字符串、解密字符串、轉換成對象,這樣一個方法還好說,多了的話重復代碼非常多,就算提取通用方法,還是要在方法里調用這個通用方法,有沒有辦法直接在參數里就封裝好這個對象?

模型綁定的對象:

public class TokenModel
{
  /// <summary>
  /// 主鍵
  /// </summary>
  public int Id { get; set; }

  /// <summary>
  /// 姓名
  /// </summary>
  public string Name { set; get; }

  /// <summary>
  /// 簡介
  /// </summary>
  public string Description { get; set; }

}

新建一個TokenBinder繼承IModelBinder接口并實現其中的BindModel方法:

public class TokenBinder : IModelBinder
{
  public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
  {
    var token = controllerContext.HttpContext.Request["token"];
    if (!string.IsNullOrEmpty(token))
    {
      string[] array = token.Split(':');
      if (array.Length == 3)
      {
        return new TokenModel() { Id = int.Parse(array[0]), Name = array[1], Description = array[2] };
      }
      else
      {
        return new TokenModel() { Id = 0 };
      }
    }
    else
    {
      return new TokenModel() { Id = 0 };
    }
  }
}

這個方法里接收了一個token參數,并對token參數進行了解析和封裝。代碼部分完成了需要到Application_Start方法里進行下注冊:

ModelBinders.Binders.Add(typeof(TokenModel), new TokenBinder());

現在模擬下這個接口:

public JsonResult TokenBinderTest(TokenModel tokenModel)
{
  var output = "Id:" + tokenModel.Id + ",Name:" + tokenModel.Name + ",Description:" + tokenModel.Description;
  return Json(new ReturnModel_Common { msg = output });
}

調用下:

ASP.NET MVC常用擴展的示例分析

可以看出,“1:汪杰:oppoic.cnblogs.com”已經被綁定到tokenModel這個對象里面了。但是如果稍復雜的模型綁定IModelBinder就無能為力了。

場景二、去除對象某個屬性的首位空格

public class Student
{
  public int Id { get; set; }

  public string Name { get; set; }

  public string Class { get; set; }
}

如果前端傳來的Name屬性有空格,如何去除呢?利用DefaultModelBinder即可實現更靈活的控制

public class TrimModelBinder : DefaultModelBinder
{
  protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
  {
    var obj = base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
    if (obj is string && propertyDescriptor.Attributes[typeof(TrimAttribute)] != null)//判斷是string類型且有[Trim]標記
    {
      return (obj as string).Trim();
    }
    return obj;
  }
}

標注下需要格式化首位屬性的實體:

[ModelBinder(typeof(TrimModelBinder))]
public class Student
{
  public int Id { get; set; }

  [Trim]
  public string Name { get; set; }

  public string Class { get; set; }
}

好了,測試下:

public JsonResult TrimBinderTest(Student student)
{
  if (string.IsNullOrEmpty(student.Name) || string.IsNullOrEmpty(student.Class))
  {
    return Json(new ReturnModel_Common { msg = "未找到參數" });
  }
  else
  {
    return Json(new ReturnModel_Common { msg = "Name:" + student.Name + ",長度:" + student.Name.Length + " Class:" + student.Class + ",長度:" + student.Class.Length });
  }
}

可見,標注了Trim屬性的Name長度是去除空格的長度:7,而沒有標注的Class屬性的長度則是6。

ASP.NET MVC常用擴展的示例分析

感謝各位的閱讀!關于“ASP.NET MVC常用擴展的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

石棉县| 满洲里市| 望江县| 辛集市| 平湖市| 甘南县| 芮城县| 察隅县| 绩溪县| 松原市| 大方县| 贵州省| 闽清县| 陆良县| 石楼县| 屏山县| 图木舒克市| 惠东县| 临漳县| 永州市| 泾川县| 手机| 呼玛县| 崇左市| 合水县| 刚察县| 阳泉市| 牡丹江市| 绩溪县| 华安县| 太原市| 百色市| 万载县| 新和县| 扶沟县| 壶关县| 郁南县| 固安县| 安义县| 黑水县| 库车县|