Agenda
前言
上一篇有介紹ModelMetadata
和參數Model
之間的關係.
MVC提供我們一個IMetadataAware
介面,讓我們可以對最終生成ModelMetadata
進行自由設定.
IMetadataAware介面
在IMetadataAware
介面有一個OnMetadataCreated
方法
1 | public interface IMetadataAware |
在MVC有預設兩個實現IMetadataAware
介面的標籤.
AllowHtmlAttribute
:標上的屬性可以攜帶Html
資料.AdditionalMetadataAttribute
:對於當前屬性的modelmetadata
資訊的AdditionalValues
添加資料(添加資料可透過ViewData.ModelMetadata.AdditionalValues
取得資料)
如果你想要對於modelmetadata
資訊做修改或新增資料可以製作自己IMetadataAware
介面標籤.
我有做一個可以針對於Asp.net MVC Debugger的專案,只要下中斷點就可輕易進入Asp.net MVC原始碼.
AllowHtmlAttribute標籤
為了防止(Cross-site scripting)XSS攻擊通過在針對某些輸入框中寫入或注入HTML
來攻擊我們Web
應用
針對HTML
標記驗證通過ModelMetadata
的RequestValidationEnabled
來控制,如下面程式碼顯示
這是一個布爾類型的可讀寫屬性。
1 | public class ModelMetadata |
此屬性在默認情況下為
True
進行驗證防護
ASP.NET MVC有一個預設標籤AllowHtmlAttribute
在進行Model
綁定之前會對對應請求資料進行驗證,確保沒有任何HTML
標記包含其中。
如果在Input
tag輸入有關Html
資料就會出現下面錯誤.(這是MVC貼心幫我們開啟防護XSS攻擊的機制)
具有潛在危險
Request.Form
的值已從用戶端 (xxxxxx) 偵測到。
如果查看AllowHtmlAttribute
原始碼就很簡單只是把metadata.RequestValidationEnabled
設成false
允許使用者上傳Html
資料.
1 | [ ] |
我們就可以把Html
資料傳送到AP端了
只是這個標籤請斟酌使用打開有一定風險.
為何可以透過實現IMetadataAware介面來擴充對於metadata操作
在AssociatedMetadataProvider
抽象類別中有個ApplyMetadataAwareAttributes
方法.
參數物件上屬性進行反射取得使用到IMetadataAware
的標籤,並呼叫他的OnMetadataCreated
方法.
1 | public abstract class AssociatedMetadataProvider : ModelMetadataProvider |
CachedDataAnnotationsModelMetadataProvider
在MVC Action
傳入參數上可以標示許多標籤例如
1 | public class VerifyCodeViewModel |
RequiredAttribute
DisplayAttribute
還有其他一大堆,下面會跟大家介紹MVC是怎麼取得並使用這些標籤,ModelMetadataProviders
這個類別會提供使用哪個ModelMetadataProvider
在原始碼建構子預設使用CachedDataAnnotationsModelMetadataProvider
1 | public class ModelMetadataProviders |
在CachedDataAnnotationsModelMetadataProvider
類別有一個CreateMetadataPrototype
方法返回一個CachedDataAnnotationsModelMetadata
物件,這個物件存放參數上屬性欄位使用標籤資訊.
1 | public class CachedDataAnnotationsModelMetadataProvider : CachedAssociatedMetadataProvider<CachedDataAnnotationsModelMetadata> |
CachedDataAnnotationsModelMetadata
CachedDataAnnotationsModelMetadata
類別上有許多屬性,主要是方便日後來判斷使用MVC使用標籤
1 | public class CachedDataAnnotationsModelMetadata : CachedModelMetadata<CachedDataAnnotationsMetadataAttributes> |
有一個蠻特別事情是CachedDataAnnotationsModelMetadata : CachedModelMetadata<CachedDataAnnotationsMetadataAttributes>
他繼承一個泛型類別CachedDataAnnotationsMetadataAttributes
存放取得物件標籤的資訊.
CachedDataAnnotationsMetadataAttributes
CachedDataAnnotationsMetadataAttributes
類別主要把屬性上的某些標籤給值到類別的屬性上,方便CachedDataAnnotationsModelMetadata
來操作使用.
這也是為什麼只有某些標籤掛在屬性上可以被使用.預設只有CachedDataAnnotationsMetadataAttributes
才會被反射取得.
1 | public class CachedDataAnnotationsMetadataAttributes |
小結:
ModelMetaData
是一個Model Binding很重要物件,裡面存放許多調用參數的資訊.
MVC提供一個IMetadataAware
介面可以改變ModelMetaData
中資訊,提高更高的彈性.
這篇也介紹了IMetadataAware
介面是在哪邊做攔截.
另外也分享常掛在屬性上標籤取得的類別跟機制
DisplayNameAttribute
RequiredAttribute
DisplayAttribute
透過CachedDataAnnotationsModelMetadataProvider
這個類別來取得以上標籤,並在日後做判斷.
下篇會和大家分享另一種屬性標籤ValidationAttribute
的取得和呼叫過程.
此文作者:Daniel Shih(石頭)
此文地址: https://isdaniel.github.io/ithelp-day20/
版權聲明:本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 TW 許可協議。轉載請註明出處!