在介绍用于自定义Model元数据属性的AdditionalMetadataAttribute特性时我们提到了它实现的接口IMedataAware,我们说这是一个非常重要并且有用的接口,通过自定义实现该接口的特性我们可以对最终生成的Model元数据进行自由地定制。如下面的代码片断所示,IMedataAware接口具有唯一的方法成员OnMetadataCreated。当Model元数据被创建出来后,会先获取上述的这一系列标注特性对其进行初始化,然后获取应用在目标元素上所有实现了IMedataAware接口的特性,并将初始化的ModelMetadata对象作为参数调用OnMetadataCreated方法。所以我们通过创建实现该接口的特性不仅仅可以添加一些额外的元数据属性,也可以修改已经通过相应的标注特性初始化的相关属性。
1: public interface IMetadataAware 2: { 3: void OnMetadataCreated(ModelMetadata metadata); 4: }
ASP.NET MVC定义了两个实现了IMedataAware接口的特性,一个就是我们已经介绍过的AdditionalMetadataAttribute,另一个则是AllowHtmlAttribute。
一、AllowHtmlAttribute
为了防止最终用于通过在针对某个数据的输入中注入一些HTML来攻击我们的Web应用,ASP.NET MVC在进行Model绑定之前会对对应的请求数据进行验证,确保没有任何HTML标记包含其中。这个针对HTML标记的验证通过ModelMetadata的RequestValidationEnabled来控制,如下面的代码片断所示,这是一个布尔类型的可读写属性。该属性在默认情况下为True,意味着默认开启针对HTML标记的请求验证。
1: public class ModelMetadata 2: { 3: //其他成员 4: public virtual bool RequestValidationEnabled { get; set; } 5: }
AllowHtmlAttribute特性,顾名思义,就是运行作为目标元素的内容包含HTML标记。如下面的代码片断所示,AllowHtmlAttribute是实现了IMetadataAware 接口,在OnMetadataCreated方法中它直接将作为参数的ModelMetadata对象的RequestValidationEnabled属性设置为False,从而使针对目标对象的请求验证被忽略掉。
1: [AttributeUsage(AttributeTargets.Property, AllowMultiple=false, Inherited=true)] 2: public sealed class AllowHtmlAttribute : Attribute, IMetadataAware 3: { 4: public void OnMetadataCreated(ModelMetadata metadata) 5: { 6: //其他操作 7: metadata.RequestValidationEnabled = false; 8: } 9: }
为了验证ASP.NET MVC针对HTML标记的请求验证和AllowHtmlAttribute的作用,我们来做一个简单的实例演示。在通过Visual Studio提供的ASP.NET MVC项目模板创建的空Web应用中,我们定义了如下一个数据类型Foo,其中属性Baz上应用了AllowHtmlAttribute特性。
1: public class Foo 2: { 3: public string Bar { get; set; } 4: 5: [AllowHtml] 6: public string Baz { get; set; } 7: }
然后我们创建如下一个默认的HomeController,默认的Index操作方法中具有一个类型为Foo的参数,该参数直接作为Model呈现在默认的View中。
1: public class HomeController : Controller 2: { 3: public ActionResult Index(Foo foo) 4: { 5: return View(foo); 6: } 7: }
如下所示的Index操作对应的View定义,这是一个以Foo为Model的强类型View。在该View中,我们直接调用HtmlHelper<Model>的EditorForModel方法将Foo对象以编辑模式呈现出来。
1: @model Foo 2: @{ 3: ViewBag.Title = "Index"; 4: } 5: @Html.EditorForModel()
现在我们直接运行该Web应用。根据Model绑定的规则我们知道,如果我们通过浏览器访问HomeController的Index操作,可以通过查询字符串的方式对该操作方法的参数进行初始化。具体来说,我们可以分别指定名称为Bar和Baz的查询字符串对作为参数的Foo对象的两个属性进行初始化。为了验证对包含HTML标记的输入的验证,我们将最终绑定到Model上的查询字符串设置为<script/>。
如下图所示,由于Foo的属性Baz上应用了AllowHtmlAttribute特性是之支持包含HTML标记的数据,所以我们以查询字符串方式指定的包含HTML标记的内容(<script/>)直接显示在相应的文本框中。但是Bar属性在默认情况下是不运行绑定的数据具有任何HTML标记的,所以会将输入的数据视为恶意注入的HTML,直接抛出异常。
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索数据
, 接口
, 标记
, 属性
, public
, 特性
, mvc参数验证
直接初始化
,以便于您获取更多的相关知识。