为何StringLengthAttribute ErrorMessage在Debug与Release模式下表现不同
问题根因
这个问题是.NET 6.0.x早期版本的IL裁剪优化bug导致,和你写的特性声明代码无关:
- Debug模式默认关闭IL裁剪与高级编译优化,
StringLengthAttribute完全按照官方源码逻辑执行String.Format,传入的三个参数顺序为0=属性名、1=最大长度、2=最小长度,格式化输出完全符合预期。 - Release模式下SDK默认开启编译优化与静态裁剪分析,裁剪器静态扫描自定义
ErrorMessage格式串时,无法正确识别非顺序排列的占位符索引,误判对应属性名的第0位参数没有被引用,直接将其从传入String.Format的参数列表中移除。最终实际参与格式化的参数只剩两个:0=最小长度6、1=最大长度7,因此{0}被替换为6,{1}被替换为7,{2}因为没有匹配的传入参数直接原样保留,就出现了错位的错误提示。
解决方案
任选以下一种方式即可修复:
- 修改项目配置,为Release编译/发布模式指定数据标注程序集不被裁剪,在csproj文件中添加如下配置段:
<PropertyGroup Condition="'$(Configuration)' == 'Release'"> <TrimmerRootAssembly Include="System.ComponentModel.DataAnnotations" /> </PropertyGroup>
- 直接将项目运行时升级到.NET 7及以上版本,这个静态裁剪的占位符识别bug已经在后续.NET正式版本中修复。
- 不自定义错误消息字符串,改用
StringLengthAttribute内置的本地化错误消息资源,规避静态裁剪对自定义格式串的误判。
内容的提问来源于stack exchange,提问作者R26
相关产品推荐
相关产品推荐

