代码之家  ›  专栏  ›  技术社区  ›  Jake Conkerton-Darby

如何使用点分隔名称的json.net camelcasepropertynamesControlResolver?

  •  0
  • Jake Conkerton-Darby  · 技术社区  · 6 年前

    我们的应用程序使用验证属性来使用ASP.NET模型验证,但是这为验证错误提供了以点分隔的名称。当通过 CamelCasePropertyNamesContractResolver 这只适用于第一个点之前的camelcase,而我们希望将camelcase应用于名称的每个部分。

    例如,我们当前得到当前的JSON响应:

    {
        "body.State": [
            "The state field is required."
        ],
        "body.LatestVersion": [
            "The latestVersion field is required."
        ]
    }
    

    但想要出去:

    {
        "body.state": [
            "The state field is required."
        ],
        "body.latestVersion": [
            "The latestVersion field is required."
        ]
    }
    

    在我们的MVC设置中,我们有一条类似于

    services.AddJsonOptions(options => options.ContractResolver = new CamelCasePropertyNamesContractResolver());
    

    我们非常感谢任何解决方案,无论是对如何设置解析器的修改,还是对验证的修改。


    编辑: 仅供参考,生成此请求的请求的模型结构如下:

    public sealed class RequestModel
    {
        [FromRoute, DisplayName("entity"), Required, MaximumLength(255)]
        public string Entity { get; set; }
    
        [FromBody, DisplayName("body"), Required]
        public BodyModel Body { get; set; }
    }
    
    public sealed class BodyModel
    {
        [DisplayName("latestVersion"), Required, MaximumLength(255)]
        public string LatestVersion { get; set; }
    
        [DisplayName("state"), Required]
        public ModelState State { get; set; }
    }
    

    正在发送的请求主体是:

    {
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   dbc    6 年前

    假设验证错误被序列化为某种类型的 IDictionary<string, T> 对于一些 T ,那么对应于字典键的JSON属性名可以在每个键之间逐段使用camel大小写。 . 通过创建自定义 naming strategy .

    json.net将逻辑封装为在 NamingStrategy 类型,具体来说 CamelCaseNamingStrategy . 修改命名策略的逻辑以应用于 . 人物,你可以采用 decorator pattern 并创建一个装饰器命名策略,将一些内部策略应用于名称的每个部分,如:

    public class PiecewiseNamingStrategy : NamingStrategy
    {
        readonly NamingStrategy baseStrategy;
    
        public PiecewiseNamingStrategy(NamingStrategy baseStrategy)
        {
            if (baseStrategy == null)
                throw new ArgumentNullException();
            this.baseStrategy = baseStrategy;
        }
    
        protected override string ResolvePropertyName(string name)
        {
            return String.Join(".", name.Split('.').Select(n => baseStrategy.GetPropertyName(n, false)));
        }
    }
    

    然后,按如下方式配置MVC:

    options.ContractResolver = new DefaultContractResolver
    {
        NamingStrategy = new PiecewiseNamingStrategy(new CamelCaseNamingStrategy()) 
        { 
            OverrideSpecifiedNames = true, ProcessDictionaryKeys = true 
        },
    };
    

    这充分利用了这样一个事实,如 reference source , CamelCasePropertyNamesContractResolver 基本上只是 DefaultContractResolver 使用A Camelcasening策略 具有 ProcessDictionaryKeys = true OverrideSpecifiedNames = true .

    笔记: