ASP.NET MVC5 ModelBinder

什么是ModelBinding

ASP.NET MVC中,所有的請求最終都會到達某個Controller中的某個Action并由該Action負責具體的處理和響應。為了能夠正確處理請求,Action的參數(如果有的話),必須在Action執行之前,根據相應的規則,把請求中所包含的數據提取出來并將映射為Action的參數值,這個過程就是ModelBinding。ModelBinding的作用就是為Action提供參數列表。

ModelBinding的好處

  1. 使代碼變得更加簡潔
  2. 幫助我們獲取HTTP請求中的數據
  3. 幫助我們完成必要的數據類型轉換

ASP.NET MVC中ModelBinding的實現過程

ASP.NET MVC中ModelBinding的實現過程比較復雜,這里簡要說明它的總體流程。具體的實現過程可以看蔣金楠的《ASP.NET MVC5框架揭秘》或者看他的博客How ASP.NET MVC Works?,講解很詳細。


  • HTTP請求中的數據可能存在于querystring中,也可能在表單中,也有可能是JSON字符串。究竟從哪里獲取數據,這要依賴于參數的描述信息ParameterDescriptor
  • ParameterDescriptor的獲取需要借助于ControllerDescriptorActionDescriptor,它們分別用來描述Controller和Action
  • IModelBinderProvider用于提供合適的ModelBinder對象,我們可以自己實現該接口以獲取自定義的IModelBinder
  • ModelBinding的核心IModelBinder,默認實現類是DefaultModelBinder,我們可以自己實現IModelBinder接口來擴展ModelBinder
  • IValueProvider針對不同的數據源提供了數據的訪問機制
  • ValueProviderResult提供了兩個ConvertTo方法重載以實現向指定目標類型的轉換。
  • 經過上述一系列的處理獲取最終結果

自定義ModelBinder

自定義Modelbinder只需實現System.Web.Mvc.IModelBinder接口即可。這里需要注意一點,System.Web.ModelBinding命名空間下也有一個IModelBinder接口,不要搞錯了。

public class LessonEditInfoViewModelBinder : IModelBinder
{//根據前臺傳遞的id值獲取對象public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext){var idStr = controllerContext.HttpContext.Request["id"] ?? controllerContext.RouteData.Values["id"]?.ToString();int id = 0;if (!int.TryParse(idStr, out id)){return null;}var model = new LessonBLL().GetLessonEditInfo(id);return model;}
}

然后使用ModelBinderAttribute進行標注即可:

/*根據前臺傳遞的id值解析出對象數據,Action無需關注對象的獲取,使代碼變得清晰簡潔
*/
public ActionResult Edit([ModelBinder(typeof(LessonEditInfoViewModelBinder))]LessonEditInfoViewModel lesson)
{if (lesson == null){//跨控制器的視圖跳轉要使用視圖的路徑+文件名return View("/Views/Exception/GenericError.cshtml", new ExceptionViewModel { Title = "404", Description = "課程不存在!" });}return View(lesson);
}

如果項目中多處需要使用自定義的ModelBinder,那么再使用ModelBinderAttribute進行標注就不大合適了。這種情況我們可以使用自定義的ModelBinderProvier。代碼如下:

public class CustomeModelBinderProvider : IModelBinderProvider
{public IModelBinder GetBinder(Type modelType){if (modelType == typeof(LessonEditInfoViewModel)){return new LessonEditInfoViewModelBinder();}return null;}
}

然后將自定義的ModelBinderProvider注冊到ASP.NET MVC系統中

public class MvcApplication : System.Web.HttpApplication
{protected void Application_Start(){ModelBinderProviders.BinderProviders.Insert(0, new CustomeModelBinderProvider());}
}

完成上述兩步之后,就無需使用ModelBuilderAttribute進行標注了。

除此之外,還可在Global文件中使用使用ModelBinder類的Binder屬性來注冊ModelBinderProvider

ModelBinders.Binders.Add(typeof(LessonEditInfoViewModel),new LessonEditInfoViewModelBinder());

不同的ModelBinder提供策略有不同的優先級,具體如下:

  1. 在參數上使用CustomModelBinderAttribute
  2. 使用ModelBinderProviders.BinderProviers
  3. 使用ModelBinders.Binders
  4. 參數類型上標記CustomModelBinderAttribute
  5. ASP.NET MVC中提供的DefaultModelBinder

注意,CustomModelBinderAttribute是抽象類,在ASP.NET MVC中有唯一子類ModelBinderAttribute。

參考文章:

Model Binders in ASP.NET MVC
ModelBinder——ASP.NET MVC Model綁定的核心
ASP.NET MVC以ValueProvider為核心的值提供系統
玩轉Asp.net MVC 的八個擴展點
ASP.NET MVC中你必須知道的13個擴展點

版權聲明

本文為作者原創,版權歸作者雪飛鴻所有。 轉載必須保留文章的完整性,且在頁面明顯位置處標明原文鏈接。

如有問題, 請發送郵件和作者聯系。

轉載于:https://www.cnblogs.com/Cwj-XFH/p/5977508.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457117.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457117.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457117.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Day07-函數(2)

1.函數類型 函數也是一種類型,我們自定義的函數就是函數對象,函數名保存了函數對象的引用(地址) def test():print(我是測試函數) ? print(test) #函數名是變量,指向了函數對象 pf test #pf變量也指向了函數對…

php在html里面的位置,關于script在html中的擺放位置解析

以前一直覺得script在html中的任何位置都可以,今天做一個需求的時候才更正了自己的錯誤思想啊--script的位置也不是隨便放的。本文主要談論關于script在html中的擺放位置。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。希望能幫助到…

Protocol Buffer技術詳解(C++實例)

原文:http://www.cnblogs.com/stephen-liu74/archive/2013/01/04/2842533.html 這篇Blog仍然是以Google的官方文檔為主線,代碼實例則完全取自于我們正在開發的一個Demo項目,通過前一段時間的嘗試,感覺這種結合的方式比較有利于培訓…

yaml 解決問題

yaml 是什么? 在 github 一些開源項目里經常可以看到 .travis.yml 文件,后來接觸持續集成這個概念時發現很多文件都是 .yml 后綴的文件。我在 阮一峰-YAML 語言教程 里了解了它的作用以及基本寫法,他的那篇文章描述的略微有點啰嗦&#xff0…

2016 7 25 鏈表

1 #include<stdio.h>2 #include<stdlib.h>3 /* 4 usingnamespacestd;5 6 structNode7 {8 int data;//數據域9 struct Node*next;//指針域10 };11 12 /*13 Create14 *函數功能&#xff1a;創建鏈表.15 *輸入&#xff1a;各節點的data16 *返回值&#xff1a;指…

php數值操作,php數值計算num類簡單操作示例

php數值計算num類簡單操作示例,在線,計算器,小數,整數,程序設計php數值計算num類簡單操作示例易采站長站&#xff0c;站長之家為您整理了php數值計算num類簡單操作示例的相關內容。本文實例講述了php數值計算num類簡單操作。分享給大家供大家參考&#xff0c;具體如下&#xff…

YAML-學習筆記!

YAML學習筆記 一、YAML簡介 YAML&#xff0c;即YAML Ain’t Markup Language的縮寫&#xff0c;YAML 是一種簡潔的非標記語言。YAML以數據為中心&#xff0c;使用空白&#xff0c;縮進&#xff0c;分行組織數據&#xff0c;從而使得表示更加簡潔易讀。 二、YAML語法 1、基本規…

CentOS遠程監控

近日&#xff0c;因工作需要&#xff0c;學習了CentOS遠程監控的水平有限&#xff0c;多指教。 遠程訪問CentOS&#xff0c;包括三種方式ssh&#xff0c;telnet&#xff0c;vnc。 本例涉及的是以vnc遠程訪問CentOS。指令在root下操作。注意&#xff1a;vnc的端口為5900&#xf…

aix oracle 10.2.0.1 升級 10.2.0.4,AIX Oracle RAC 升級到10.2.0.4.0要特別注意的問題 - 愛肯的專欄 ......

AIX Oracle RAC 升級到10.2.0.4.0過程有如下報錯(直接升級到10.2.0.4不需要應用Patch:6160398)&#xff1a;rootbwgl_db2:/u01/app/oracle/crs_1/bin# /u01/app/oracle/crs_1/install/root102.shError : Please change the CRS_ORACLE_USER id to have the following OS capabi…

將文件提交到github的兩種方法

方法一 簡要步驟如下&#xff1a; 登陸github&#xff0c;創建git倉庫。記此git倉庫的地址為[github_repository_url]&#xff0c;例如git倉庫的地址&#xff1a;https://github.com/galian123/nodejs_http_server 在本地的工程目錄執行git init&#xff0c;此工程目錄是要提…

Visual Studio 2017新版發布,極大提高開發效率丨附下載

最新的Visual Studio 2017免費下載&#xff1a;https://www.evget.com/product...【包含Professional、Enterprise、Community版本】 為任何開發、應用和平臺提供無與倫比的效率&#xff0c;Visual Studio 2017 候選發布。 提高了效率 代碼導航、IntelliSense、重構、代碼修復和…

BGP路由協議詳解(完整篇)

原文鏈接&#xff1a;http://xuanbo.blog.51cto.com/499334/465596/ 2010-12-27 12:02:45 上個月我寫一篇關于BGP協議的博文&#xff0c;曾許諾過要完善這個文檔&#xff0c;但因最近的工作和授課很忙&#xff0c;所以沒有時間進行完善。為了實現這個承諾&#xff0c;我在去外…

oracle 備份導出,oracle 怎么備份或導入導出表

exp/imp下面介紹的是導入導出的實例&#xff0c;向導入導出看實例基本上就可以完成&#xff0c;因為導入導出很簡單。數據導出&#xff1a;1 將數據庫TEST完全導出,用戶名system 密碼manager 導出到D:\daochu.dmp中exp system/managerTEST filed:\daochu.dmp fully2 將數據庫中…

GitHub+Hexo搭建自己的Blog之-本地環境部署01

前言 之前我的博客沒有綁自己的域名&#xff0c;一直在github上放著&#xff0c;訪問起來比較麻煩&#xff0c;前陣子在阿里云買了這個域名&#xff0c;配置上之后&#xff0c;就可以通過自己的域名訪問了&#xff0c;有些朋友問我這個博客怎么搭的&#xff0c;用的什么主題&am…

appsettings 連接oracle數據庫,ABP .net core集成訪問Oracle數據庫

1.添加包引用&#xff1a;Microsoft.EntityFrameworkCore.RelationalOracle.EntityFrameworkCore2.重寫DbContext OnModelCreating/// /// 判斷如果是Oracle&#xff0c;需要執行Schema/// /// protected override void OnModelCreating(ModelBuilder modelBuilder){//判斷當前…

Day08-函數(3)

import functools #偏函數 def demo(a,b,c,d):print(a,b,c,d)# def partital_demo(a,b): # demo(a,b,3,4) # partital_demo(1,2)#實現偏函數 # #固定前兩個 # demo functools.partial(demo,5,6) # demo(10,50)# #固定后兩個 # demofunctools.partial(demo,c3,d5) # demo(1…

使用VS2010編譯Qt 5.6.1過程記錄

由于Qt官方發布的Qt 5.6.1二進制安裝包沒有對應VS2010版本的&#xff0c;而我的電腦上只安裝了VS2010&#xff0c;因此只能自己編譯。 本文記錄本人的編譯安裝過程&#xff0c;以及其中遇到的一些問題。 本文使用VS2010 32位編譯Qt 5.6.1。 1. 下載Qt源代碼 Qt源代碼下載地址&…

golang 指針

指針1、簡單的定義一個指針package mainimport "fmt"func main(){var p *inti :2p &ifmt.Println("memory address i:",p) } //執行結果&#xff1a; memory address i: 0xc42000a2e02、打印指針的值package mainimport "fmt"func main(){v…

php防錯處理,更好的PHP錯誤處理

錯誤類型PHP 主要有兩種錯誤&#xff1a;觸發錯誤和異常。其中觸發錯誤大概可以分為&#xff1a;編譯錯誤、引擎錯誤和運行時錯誤&#xff0c;其中前兩個是無法捕獲的&#xff1b;異常都是可以捕獲的&#xff0c;當沒有嘗試捕獲時則會中斷代碼。觸發錯誤可以通過 error_get_las…

Windows安裝Apache注冊服務出現(OS 5)拒絕訪問。 : AH00369: Failed to open the Windows service manager,

windows安裝Apache&#xff0c;注冊服務出現“(OS 5)拒絕訪問。 : AH00369: Failed to open the WinNT service manager..."錯誤 在安裝Apache的時候&#xff0c;我下載的是zip格式&#xff0c;不是msi安裝版&#xff0c;需要自己注冊服務&#xff0c;才能在桌面任務欄里有…