發(fā)文章
發(fā)文工具
撰寫
網(wǎng)文摘手
文檔
視頻
思維導(dǎo)圖
隨筆
相冊(cè)
原創(chuàng)同步助手
其他工具
圖片轉(zhuǎn)文字
文件清理
AI助手
留言交流
MVC通過路由系統(tǒng),根據(jù)url找到對(duì)應(yīng)的Action,然后再執(zhí)行action,在執(zhí)行action的時(shí)候,根據(jù)action的參數(shù)和數(shù)據(jù)來源比對(duì),生成各個(gè)參數(shù)的值,這就是model binder.
MVC中這個(gè)核心處理邏輯都在ControllerActionInvoker里,用reflector看,能看能到這個(gè)類繼承了IActionInvoker接口
1 public interface IActionInvoker 2 { 3 bool InvokeAction(ControllerContext controllerContext, string actionName); 4 }
所以咱們可以根據(jù)代碼模擬寫出自己的CustomActionInvoker
以下是我自己寫的ActionInvoker類
1 public class CustomActionInvoker : IActionInvoker 2 { 3 4 public bool InvokeAction(ControllerContext controllerContext, string actionName) 5 { 6 bool flag = false; 7 try 8 { 9 //get controller type 10 Type controllerType = controllerContext.Controller.GetType(); 11 //get controller descriptor 12 ControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(controllerType); 13 //get action descriptor 14 ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName); 15 Dictionary<string, object> parameters = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase); 16 //get parameter-value entity 17 foreach (ParameterDescriptor parameterDescriptor in actionDescriptor.GetParameters()) 18 { 19 Type parameterType = parameterDescriptor.ParameterType; 20 //get model binder 21 IModelBinder modelBinder = new CustomModelBinder(); 22 IValueProvider valueProvider = controllerContext.Controller.ValueProvider; 23 string str = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName; 24 ModelBindingContext bindingContext = new ModelBindingContext(); 25 bindingContext.FallbackToEmptyPrefix = parameterDescriptor.BindingInfo.Prefix == null; 26 bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, parameterType); 27 bindingContext.ModelName = str; 28 bindingContext.ModelState = controllerContext.Controller.ViewData.ModelState; 29 bindingContext.ValueProvider = valueProvider; 30 parameters.Add(parameterDescriptor.ParameterName, modelBinder.BindModel(controllerContext, bindingContext)); 31 } 32 ActionResult result = (ActionResult)actionDescriptor.Execute(controllerContext, parameters); 33 result.ExecuteResult(controllerContext); 34 flag = true; 35 } 36 catch (Exception ex) 37 { 38 //log 39 } 40 return flag; 41 } 42 }
以下詳細(xì)解釋下執(zhí)行過程
執(zhí)行過程中涉及到三個(gè)Descriptor,ControllerDescriptor,ActionDescriptor,ParameterDescriptor
ControllerDescriptor主要作用是根據(jù)action name獲取到ActionDescriptor,代碼中使用的是MVC自帶的ReflectedControllerDescriptor,從名字就可以看出來,主要是靠反射獲取到action.
ActionDescriptor,主要作用是獲取parameterDescriptor,然后execute action.
parameterDescriptor,描述的是action的參數(shù)信息,包括name、type等
最核心的方法. 將傳遞的數(shù)據(jù)和參數(shù)一一對(duì)應(yīng),筆者是自己寫的CustomModelBinder,MVC默認(rèn)用的是DefaultModelBinder 都實(shí)現(xiàn)了接口IModelBinder
1 public interface IModelBinder 2 { 3 object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext); 4 }
其中CustomModelBinder的代碼如下
1 public class CustomModelBinder : IModelBinder 2 { 3 4 public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 5 { 6 return this.GetModel(controllerContext, bindingContext.ModelType, bindingContext.ValueProvider, bindingContext.ModelName); 7 } 8 9 public object GetModel(ControllerContext controllerContext, Type modelType, IValueProvider valueProvider, string key) 10 { 11 if (!valueProvider.ContainsPrefix(key)) 12 { 13 return null; 14 } 15 return valueProvider.GetValue(key).ConvertTo(modelType); 16 } 17 }
注:我只是實(shí)現(xiàn)了簡(jiǎn)單的基本類型
中間有最核心的方法
valueProvider.GetValue(key).ConvertTo(modelType)
MVC默認(rèn)提供了幾種ValueProvider,每種都有對(duì)應(yīng)的ValueProviderFactory,每種ValueProvider都對(duì)應(yīng)著自己的數(shù)據(jù)源
1 ValueProviderFactoryCollection factorys = new ValueProviderFactoryCollection(); 2 factorys.Add(new ChildActionValueProviderFactory()); 3 factorys.Add(new FormValueProviderFactory()); 4 factorys.Add(new JsonValueProviderFactory()); 5 factorys.Add(new RouteDataValueProviderFactory()); 6 factorys.Add(new QueryStringValueProviderFactory()); 7 factorys.Add(new HttpFileCollectionValueProviderFactory());
上述過程講完之后,還缺一個(gè)怎么應(yīng)用上自己寫的ActionInvoker,在Controller里提供了虛方法CreateActionInvoker
1 protected override IActionInvoker CreateActionInvoker() 2 { 3 return new CustomActionInvoker(); 4 }
到此,整個(gè)過程已講完。
來自: 昵稱10504424 > 《工作》
0條評(píng)論
發(fā)表
請(qǐng)遵守用戶 評(píng)論公約
白話學(xué)習(xí)MVC(六)模型綁定
在這個(gè)自定義的ModelBinder中對(duì)復(fù)雜類型的綁定時(shí),只能綁定上述User類那樣的類型,但是在實(shí)際中還有存在嵌套類型的類,例如:public class User{ public int Id{set;get;} public string Name{set...
Asp.net MVC 示例項(xiàng)目Suteki.Shop分析之---ModelBinder
aaa
aaaModel.prototype.addCartButtonClick = function(event){var row = event.bindingContext.$object;if( rows.length == 0 ){this.comp("cartData").newData({defaultValues:[{"fMenuI...
ASP.NET MVC 流程概述(轉(zhuǎn))
if (View == null) { result = FindView(context);1)進(jìn)入 result = FindView(context); 其實(shí) 調(diào)用的是ViewResult的Find...
NetCore3.0實(shí)現(xiàn)自定義IOC容器注入
foreach (var lib in libs) { if (!public class CloudControllerActivator : IControllerActivator { public object Create(ControllerContext context) { if (context == null) { throw new Argument...
我喜歡ASP.NET的MVC因?yàn)樗1频?大理由
我很早就關(guān)注ASP.NET的mvc的,因?yàn)樽铋_始是學(xué)了Java的MVC,由于工作的原因一直在做.Net開發(fā),最近的幾個(gè)新項(xiàng)目我采用了MVC做了,我個(gè)一...
從零開始學(xué)習(xí) ASP.NET MVC 1.0 (四) View/Model 全解
} return new ViewResult { View = view, ViewData = ViewData, TempData = TempData };ViewData的生命周期和View相同, 只對(duì)當(dāng)前View有...
消失模鑄造工藝分類及特點(diǎn) classification and characteristics
Thelost foam casting can be divided into self-hardening sand (damp type with binder) lost foam casting anddry sand (dry type without binder ) lost foam casting according to its castmould...
[ASP.NET MVC 小牛之路]15
<form action="/Home/Names" method="post"> <div><label>1:</label><input id="...
微信掃碼,在手機(jī)上查看選中內(nèi)容