了解.net mvc实现原理ActionResult/View
上一篇了解了请求至Controller的Action过程,这篇继续看源码处理Action收到请求数据再返回ActionResult到View的过程。
本节要讨论的问题
Action的传参过程
ActionResult
IView / IViewEngine / ViewEngineCollection / ViewEngineResult
记得上篇反编译源看到Filter的执行顺序提到命名1,2,3的变量,在MVC3的源码中这个微软改掉了。
AuthorizationContext authContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor);ActionExecutedContext postActionContext = InvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters);ExceptionContext exceptionContext = InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex);一、Action的传参过程
我们在定义Action方法时常用的传参大致有这么几种,详细看代码注释
View Code
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Web;using System.Web.Mvc;using System.ComponentModel;using Demo.Model;using Demo.Service.IService;namespace Demo.Mvc.Controller{ [HandleError] public class MenuController:Core.BaseController { private IMenuService service; public MenuController(IMenuService service) { this.service = service; } public ActionResult Index() { return View(); } [ActionName("ShowId")] public ActionResult ShowId(string id) { return View(service.Get(id)); } //UpdateModel 缺点失败会抛出异常 or TryUpdateModel方式会试转换时间整数等NULL字段 public ActionResult SaveModel(string name, string age) { var permisson = new INFRA_MENU_PERMISSION(); //UpdateModel<INFRA_MENU_PERMISSION>(permisson); TryUpdateModel(permisson); ViewData.Model = permisson; return View(); } //FormCollection 的方式 //可以绑定任意集合类型:IList<Book>, ICollection<Book>, IEnumerable<Book>, List<Book>, Book[] 字典 public ActionResult SaveModel(FormCollection formCollection) { INFRA_MENU_PERMISSION permisson = new INFRA_MENU_PERMISSION(); permisson.ACTION_NAME = formCollection["ACTION_NAME"]; permisson.CREATETIME = Convert.ToDateTime(formCollection["ACTION_NAME"]); service.Update(permisson); return RedirectToAction("Index"); } //IModelBinder DefaultModelBinder将Request传递参数绑定到对象上 [OutputCache] public ActionResult SaveModel(INFRA_MENU_PERMISSION permisson) { service.Update(permisson); return RedirectToAction("Index"); } //不绑定哪些属性 public ActionResult SaveModelWithExclude([Bind(Exclude = "CONTROLLER_NAME")]INFRA_MENU_PERMISSION permisson) { service.Update(permisson); return RedirectToAction("Index"); } //绑定哪些属性 public ActionResult SaveModelWithInclude([Bind(Include = "CONTROLLER_NAME")]INFRA_MENU_PERMISSION permisson) { service.Update(permisson); return RedirectToAction("Index"); } } } Action传参支持类型绑定,字典键,对象,集合等等。除了使用默认的绑定方式,还可以继承IModelBinder重写DefaultModelBinder。
自己实现一个ModelBinder的代码 以及处理绑定的Attribute (具体看代码注释),可以通过这种方式解决一些复杂对象的值绑定问题。
View Code
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using System.ComponentModel;namespace Demo.Mvc.ExModelBinder{ //实现类似DefaultModelBinder 参照一下DefaultModelBinder源码重写个ModelBinder //DefaultModelBinder 在MVC2和MVC3的源码是不同的,主要是ValueProvider这个字段 MVC2是字典个集合,MVC3是个策略模式 public class VOModelBinder : IModelBinder { #region IModelBinder 成员 public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { object model = Activator.CreateInstance(bindingContext.ModelType); PropertyDescriptorCollection col = TypeDescriptor.GetProperties(model); foreach (PropertyDescriptor item in col) { //ValueProvider记录Request参数键值对 var result = bindingContext.ValueProvider.GetValue(item.Name); if (result != null) { var value = result.ConvertTo(item.PropertyType); item.SetValue(model, value); &a
补充:Web开发 , ASP.Net ,