惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cisco Talos Blog
Cisco Talos Blog
Martin Fowler
Martin Fowler
A
About on SuperTechFans
H
Help Net Security
F
Full Disclosure
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
IT之家
IT之家
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
阮一峰的网络日志
阮一峰的网络日志
WordPress大学
WordPress大学
H
Heimdal Security Blog
博客园_首页
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
Tailwind CSS Blog
Recent Announcements
Recent Announcements
B
Blog RSS Feed
Last Week in AI
Last Week in AI
V2EX - 技术
V2EX - 技术
The Register - Security
The Register - Security
Security Archives - TechRepublic
Security Archives - TechRepublic
G
GRAHAM CLULEY
美团技术团队
S
Securelist
MyScale Blog
MyScale Blog
Vercel News
Vercel News
L
LINUX DO - 最新话题
Hacker News: Ask HN
Hacker News: Ask HN
W
WeLiveSecurity
M
MIT News - Artificial intelligence
宝玉的分享
宝玉的分享
月光博客
月光博客
Attack and Defense Labs
Attack and Defense Labs
大猫的无限游戏
大猫的无限游戏
博客园 - Franky
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Microsoft Security Blog
Microsoft Security Blog
I
InfoQ
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Forbes - Security
Forbes - Security
罗磊的独立博客
O
OpenAI News
AI
AI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
雷峰网
雷峰网
S
Security @ Cisco Blogs
MongoDB | Blog
MongoDB | Blog
Schneier on Security
Schneier on Security
P
Proofpoint News Feed
Webroot Blog
Webroot Blog
V
Visual Studio Blog

博客园 - 无常

用 Zig 写了个 MCP Server,让 AI Agent 直接操控你的 Outlook ABP点滴:API无权访问资源时,返回 PolicyName 信息 使用MSBUILD 构建时出错 error MSB3086: Task could not find "sgen.exe" using the SdkToolsPath PPTPD默认MTU太大引起一些网站上不了的问题 CentOS 6.0 安装配置rails 2.3.11 + redmine 1.2.1 笔记 MVC3中实现验证提示信息多语言支持 MVC3中使用验证适配器修改默认的验证提示信息 nginx 截断日志一个批处理 在没有安装有mvc3的主机上部署asp.net mvc3网站,需要包含的DLL文件 ASP.NET MVC 2 RTM client side validation一个隐秘的坑 Python:使用ctypes库调用外部DLL NHibernate+Oracle 遇到ORA-01461和ORA-01084及解决方法 ASP.NET MVC中实现多个按钮提交的几种方法 - 无常 - 博客园 为cnblogs定做一个代码插入代码的windows live writer插件 Code: jsTree ajax 选择行政区域 送出15个Google Wave邀请,需要的赶快 GeekOS:Project1. Loading Executable Files GeekOS:二、Project0 GeekOS: 一、构建基于Ubuntu9.04的实验环境 动刀EFOracleProvider,使其支持char、timestamp(x)等类型
MVC 2.0: ConvertEmptyStringToNull 带来烦恼
无常 · 2010-01-20 · via 博客园 - 无常

2010-01-20 18:34  无常  阅读(2643)  评论()    收藏  举报

把一个mvc1.0的项目迁移到2.0遇到了些问题,部分表更新时提示某字段值不能为NULL,跟踪发现表单中为没填写的字符串类型字段都为null。

下载2.0源码,发现DefaultModelBinder有了不少改动,找到了源头:

 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中:

 DisplayFormatAttribute displayFormatAttribute = attributeList.OfType().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,则按照此属性设置的ConvertEmptyStringToNull值。

可是我项目中之前并没有给模型设置有DataAnnotations Attribute!

再找到ModelMetadata类的定义,发现其private bool _convertEmptyStringToNull = true; !

ModelMetadata.ConvertEmptyStringToNull默认值竟是true!

自己写个ModelMetadataProvider来解决此问题:

 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:

 protected void Application_Start()
{
    ModelMetadataProviders.Current = new GUET.OA.Web.Mvc.NoConvertStringMetadataProvider();
}

mvc 2.0功能加了挺多,比如这个DataAnnotation Metadata,让我们在验证上节省了不少时间。

先吃螃蟹的人问题要付出些代价的。