MVC 2.0: ConvertEmptyStringToNull 带来烦恼
2010-01-20 18:34 无常 阅读(2622) 评论(2) 编辑 收藏 举报把一个mvc1.0的项目迁移到2.0遇到了些问题,部分表更新时提示某字段值不能为NULL,跟踪发现表单中为没填写的字符串类型字段都为null。
下载2.0源码,发现DefaultModelBinder有了不少改动,找到了源头:
1 2 3 4 5 6 7 8 9 | protected virtual object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) { object value = propertyBinder.BindModel(controllerContext, bindingContext); if (bindingContext.ModelMetadata.ConvertEmptyStringToNull && Object.Equals(value, String.Empty)) { return null ; } return value; } |
这里多了个步骤,如果ModelMetadata的ConvertEmptyStringToNull属性为true,则把空字符串转为null。
ConvertEmptyStringToNull值从何来?再找到到DataAnnotationsModelMetadataProvider中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | DisplayFormatAttribute displayFormatAttribute = attributeList.OfType<displayformatattribute>().FirstOrDefault(); if (displayFormatAttribute == null && dataTypeAttribute != null ) { displayFormatAttribute = dataTypeAttribute.DisplayFormat; } if (displayFormatAttribute != null ) { result.NullDisplayText = displayFormatAttribute.NullDisplayText; result.DisplayFormatString = displayFormatAttribute.DataFormatString; result.ConvertEmptyStringToNull = displayFormatAttribute.ConvertEmptyStringToNull; if (displayFormatAttribute.ApplyFormatInEditMode) { result.EditFormatString = displayFormatAttribute.DataFormatString; } } </displayformatattribute> |
如果属性有DisplayFormatAttribute,则按照此属性设置的ConvertEmptyStringToNull值。
可是我项目中之前并没有给模型设置有DataAnnotations Attribute!
再找到ModelMetadata类的定义,发现其private bool _convertEmptyStringToNull = true; !
ModelMetadata.ConvertEmptyStringToNull默认值竟是true!
自己写个ModelMetadataProvider来解决此问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public class MyDataAnnotationsModelMetadataProvider : DataAnnotationsModelMetadataProvider { protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func< object > modelAccessor, Type modelType, string propertyName) { var md = base .CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName); DataTypeAttribute dataTypeAttribute = attributes.OfType<DataTypeAttribute>().FirstOrDefault(); DisplayFormatAttribute displayFormatAttribute = attributes.OfType<DisplayFormatAttribute>().FirstOrDefault(); if (displayFormatAttribute == null && dataTypeAttribute != null ) { displayFormatAttribute = dataTypeAttribute.DisplayFormat; } if (displayFormatAttribute == null ) { md.ConvertEmptyStringToNull = false ; } return md; } } |
最后,还需要在Application_Start中替换掉默认的ModelMetadataProvider:
1 2 3 4 | protected void Application_Start() { ModelMetadataProviders.Current = new GUET.OA.Web.Mvc.NoConvertStringMetadataProvider(); } |
mvc 2.0功能加了挺多,比如这个DataAnnotation Metadata,让我们在验证上节省了不少时间。
先吃螃蟹的人问题要付出些代价的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
2007-01-20 [翻译]jQuery 选择器的使用