ASP.NET MVC 视图(三)

前言

上篇对于Razor视图引擎和视图的类型做了大概的讲解,想必大家对视图的本身也有所了解,本篇将利用IoC框架对视图的实现进行依赖注入,在此过程过会让大家更了解的视图,最后还会简单的介绍一下自定义的视图辅助器是怎么定义和使用的。


ASP.NET MVC 视图

l 自定义视图引擎

lRazor视图引擎执行过程

lRazor视图的依赖注入、自定义视图辅助器

l 分段、分部视图的使用

l Razor语法、视图辅助器



Razor视图的依赖注入

首先我们来看一下要定义实现依赖注入的功能接口规范和默认实现,示例代码1-1.

代码1-1

usingSystem.Web.Mvc;usingNinject;namespaceMvcApplication.Models{publicinterfaceIStringManage{MvcHtmlStringCombinationString(stringstrPar1,stringstrPar2);}publicclassDefaultStringManage:IStringManage{publicMvcHtmlStringCombinationString(stringstrPar1,stringstrPar2){returnnewMvcHtmlString(strPar1+strPar2);}}}


在IStringManage类型中定义了CombinationString()方法,用于将两个字符串类型的数值拼接起来,DefaultStringManage类型就是默认实现了,这里就不多说了。

下面我们再来定义在编译时刻视图将要实现继承的类型,示例代码1-2

代码1-2

usingSystem.Web.Mvc;usingNinject;namespaceMvcApplication.Models{publicabstractclassStringManageView:WebViewPage{[Inject]publicIStringManageStringManage{get;set;}}}


这样的定义起初是不会有什么问题的,因为cshtml视图文件在编译时是继承自WebViewPage类型的,现在我们要让cshtml视图所继承的类型是StringManageView,所以必须让StringmanageView继承自WebViewPage,因为WebViewPage是抽象类型,而我们又不想实现什么所以要定义为抽象类型,在StringManageView类型中,我定义了IStringManage类型的属性StringMange,并且使用IoC框架中的Inject特性来描述它,使的在编译是可以通过IoC来实现属性的依赖注入。

下面我们来看一下视图代码,这里的视图代码还是引用前面篇幅使用最多的一个示例,代码1-3和代码1-4

代码1-3

publicActionResultIndex(List<Product>model){ViewBag.StrPar1="Thisis";ViewBag.StrPar2="ViewIoCCase";returnView(model);}


代码1-4

@inheritsMvcApplication.Models.StringManageView@{ViewBag.Title="Index";}<h3>Index</h3>@foreach(variteminModel){<h4>ID:@item.IDName:@item.Name</h4>}<h3>@StringManage.CombinationString(ViewBag.StrPar1,ViewBag.StrPar2)</h3>


控制器方法部分的代码定义是没有问题的,在代码1-4,也就是Index视图的定义中通过@inherits指令来使视图文件在编译时继承自某个类型,以及在下面的使用中用到了StringManage属性,并且还调用了方法,这里看起来都没什么问题,但是放在这里用就有问题了,因为上面使用了foreach来遍历Model,在我们定义StringManageView的时候并没有对Model的类型做约束什么的,而控制器方法中也是需要将List<Product>类型传递到视图的,这里就引起了冲突,图1.

图1

遇到这种情况我们只需修改一下代码1-2中的定义,让Model类型是在编译时是可确定的而不是object类型,来看代码1-5

代码1-5

publicabstractclassStringManageView:WebViewPage<dynamic>{[Inject]publicIStringManageStringManage{get;set;}}


对的,让StringManageView实现泛型的WebViewPage就可以了,上个篇幅中视图的基类也都是这样定义的,不是说上面代码1-2定义的就是错误的,定义的没有错,只是应用的视图不合适,因为Index视图本身需要对Model做一些操作,又不想因为为视图添加的依赖注入功能而修改所以才会引起的这个错误,如果放在普通的视图里使用那是没有问题的。

上面这些都定义好了,下面我们需要实现自定义的IDependencyResolver类型,目的在于绑定我们需要进行依赖注入的功能模块到IoC中,代码1-6.

代码1-6

usingNinject;usingSystem.Web.Mvc;namespaceMvcApplication.CustomDependencyResolver{publicclassNinjectDependencyResolver:IDependencyResolver{privateIKernelKernel;publicNinjectDependencyResolver(){Kernel=newStandardKernel();AddBinding();}privatevoidAddBinding(){Kernel.Bind<Models.IStringManage>().To<Models.DefaultStringManage>();}publicobjectGetService(TypeserviceType){returnthis.Kernel.TryGet(serviceType);}publicIEnumerable<object>GetServices(TypeserviceType){returnthis.Kernel.GetAll(serviceType);}}}

对于代码1-6就不作过多的解释了,在控制器激活部分都讲解过近乎类似的注入封装类型。

最后我们在Global.asax文件的Application_Start()方法中,将Model绑定器和NinjectDependencyResolver类型添加中MVC框架中,代码1-7

代码1-7

ModelBinders.Binders.Add(typeof(List<Product>),newCustomListModelBinder());DependencyResolver.SetResolver(newCustomDependencyResolver.NinjectDependencyResolver());

最后看下结果,图2.

图2

自定义视图辅助器

实际上自定义视图辅助器就是扩展方法的定义,首先我们来看定义,实现的功能同代码1-1相同,代码2-1

usingSystem.Web.Mvc;namespaceMvcApplication.CustomHtmlHelper{publicstaticclassMyCustomHtmlHelper{publicstaticMvcHtmlStringCombinationString(thisHtmlHelperhtmlHelper,stringstrPar1,stringstrPar2){returnnewMvcHtmlString(strPar1+strPar2);}}}


代码2-1这样的一个类型也就是自定义视图辅助器了,当然了这只是一个简单的示例,现在我们需要把它在视图中使用起来,我们得先把这个自定义的视图辅助器所在的命名空间添加到Views文件中的Web.Config中,代码2-2.

代码2-2

<system.web.webPages.razor><hostfactoryType="System.Web.Mvc.MvcWebRazorHostFactory,System.Web.Mvc,Version=3.0.0.0,Culture=neutral,PublicKeyToken=31BF3856AD364E35"/><pagespageBaseType="System.Web.Mvc.WebViewPage"><namespaces><addnamespace="System.Web.Mvc"/><addnamespace="System.Web.Mvc.Ajax"/><addnamespace="System.Web.Mvc.Html"/><addnamespace="System.Web.Routing"/><addnamespace="MvcApplication.CustomHtmlHelper"/></namespaces></pages></system.web.webPages.razor>


然后是在视图中引用扩展方法所处的命名空间,这样配置过后就可以在视图用运用了我们刚刚自定义的视图辅助器了,代码2-3.

代码2-3

@inheritsMvcApplication.Models.StringManageView@usingMvcApplication.CustomHtmlHelper@{ViewBag.Title="Index";}<h3>Index</h3>@foreach(variteminModel){<h4>ID:@item.IDName:@item.Name</h4>}<h3>@StringManage.CombinationString(ViewBag.StrPar1,ViewBag.StrPar2)</h3>@Html.CombinationString("Thisisa","Case")


最后我们看一下结果如图3.

图3