最近在項目中遇到一個問題,在前端調用Action的時候,MVC會使用DefaultModelBinder做默認的數據類型映射。但是會把前端的string.Empty映射為null。
感謝http://blog.csdn.net/dz45693/article/details/8169656這篇博客,提供了ModelBinder的映射過程的說明,找到了BindProperty這個方法應該是映射的具體實現。然后通過Reflector.exe這個強大的反編譯工具,在System.Web.Mvc.dll這個dll,找到了BindProperty這個方法的內部實現,具體是通過GetPropertyValue這個方法去給參數賦值的。具體代碼如下:
1 protected virtual object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) 2 { 3 object objA = propertyBinder.BindModel(controllerContext, bindingContext); 4 if (bindingContext.ModelMetadata.ConvertEmptyStringToNull && object.Equals(objA, string.Empty)) 5 { 6 return null; 7 } 8 return objA; 9 } 10 11 12 13
可以很清楚的看到,會把string.Empty給轉換成為null。那么就只要override GetPropertyValue方法,就可以解決問題了。具體代碼如下:
1 protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) 2 { 3 object objA = propertyBinder.BindModel(controllerContext, bindingContext); 4 if (bindingContext.ModelMetadata.ConvertEmptyStringToNull && object.Equals(objA, string.Empty)) 5 { 6 return string.Empty; 7 } 8 return objA; 9 10 }
然后在Application_Start里使用剛剛重寫的ModelBinder作為默認的ModelBinder就可以了。
1 System.Web.Mvc.ModelBinders.Binders.DefaultBinder = new ModelBinderProvider();
MVC 3 的ModelBinder機制還是挺強大的,支持各種復雜類型的映射,包括各種集合類型的映射。你也可以去實現IModelBinder這個接口去實現一個自定義的ModelBinder。在此推薦一下博客http://blog.csdn.net/dz45693/article/details/8169656這個系列文章,里面是MVC的源碼分析,幫你能更深入的理解MVC的運行機制。