前言
之前就有写过一篇 <<前后端沟通 naming conversion 转换需要知道的事>>
这篇做一个总结整理.
我们知道 C# 的 Property 是 PascalCase, 而 Javascript 是 camelCase. 2 者要沟通就需要转换.
简单的理解就是把 PascalCase 的第一字变成小写. 就变成了 camelCase. 在大部分的情况下这个是对的. 直到遇上缩写.
比如: DLPDate, FSBCert, CADDesigner (没办法, 不可能强制世界没有缩写)
如果只是把第一个字变成小写就成了 dLPDate, fSBCert, cADDesigner
而比较正确的是 dlpDate, fsbCert, cadDesigner. 所以当有用到缩写时, 都需要额外注意哦.
涉及范围
System.Text.Json
Web API post data 和 response data 的时候. PascalCase 和 camelCase 转换
OData
Web API response data 的时候, PascalCase to camelCase
Swagger
估计它就是基于 System.Text.Json 和 OData 的
FluentValidation
Response error 的时候 property name 和 display name. PascalCase to camelCase and Title Case.
默认行为 & Override
System.Text.Json
FirstName -> firstName
CADDesigner -> cadDesigner (哎哟, 它不是简单的把第一字变小写而已哦)
CADDesignerCADDesigner -> cadDesignerCADDesigner (哎哟, 第 2 个 CAD 就没有处理了)
它是什么机制呢 ? 看源码
第 52 行负责把字变小.
第 33 行判断如果第 2 个字是小写, 那么直接中断. 也就等于单纯的把第一个字变小, 后续就不管了. (所以 FirstNAME -> firstNAME, 后面的 NAME 是不管的了)
如果第 2 个字不是小写, 而是连续的大写. 那么就不会中断, 会一直连续变小.
直到第 41 行, 下一个字是小写. (所以...一开始连续大写, 一直变小, 直到第一个小写出现)
比如 CADDesigner 一直到下一个小写就是 Designer 的 D 位置, 中断.
中断前还有一个判断, 第 44 行, 下一个小写的字母是不是一个空格. 如果不是的话, 那么当前这个字保留大写
比如 CADDesigner 到 index 3 "D" 最终是 cadDesigner, D 保留了大写.
如果是 CAD Designer 那么到 index 2 "D" 下一个是空格, 然后它变小, 然后中断, 就成了 cad Designer
从这里可以知道, 它虽然有处理缩写, 但只是处理开头几个字的缩写而已. 所以还是要多留意哦.
如果遇到它转换不对, 可以使用 JsonPropertyName 来解决.
OData & Swagger
OData 虽然没有用 System.Text.Json, 但效果是一样的 (我没有去查源码, 只是简单测一下)
OData 不支持 JsonPropertyName, 如果要换 PropertyName 可以用传统的 [DataContract] (不推荐, 因为要写全套, 每一个 Property 都要写 Attribute)
还有一个方法是在 builder 的时候 EntitySetConfig.Property(e => e.Name).Name = "NewName"
But, 这个虽然可以换 PropertyName 但是并不能换 Case Style 哦. 如果想解决 camelCase 缩写转换不准的问题, 就得写一个 Formmater.
FluentValidation
FluentValidation 返回 Error Property 默认是 PascalCase 的.
Issue: Add option to camelCase property names
解决方式是写一个 Resolver
里面是这样的
拿到相关的 information 后, 就可以返回想要的逻辑了.
另外一个要注意的点是, 一旦改了 property name, 整个作用域的 property 就换掉了哦, 比如在 Must 里, 本来可以通过 PropertyName 去做些反射, 就变得不可以了 (也不是很糟糕啦, 最多就是外面传进来咯)
还有一点是 DisplayName 是通过 PropertyName 生成的, 所以如果你换了 PropertyName, DisplayName 也会改变.
ClassPropertyName -> FluentPropertyName -> FluentDisplayName
如果也提供了 DisplayNameResolver 就变成
ClassPropertyName -> FluentDisplayName 了.
总结
1. FluentValidation 必须实现一个 camelCase property name resolver
2. 如果没有缩写, 什么也不必烦.
3. 如果只是前面缩写, 那么也不必烦.
4. 如果缩写翻车, 建议是闪, 如果真的闪不掉. 用 JsonPropertyName, OData 就写一个 Formatter 解析 JsonPropertyName.