当前位置: 首页 > 知识库问答 >
问题:

如何制作JSON。网络转换器使用连字符分隔的外壳

徐栋
2023-03-14

我使用一个API,它返回如下字符串值:

一些枚举值

我尝试将这些值放入enum中,因为默认的StringEnumConverter不符合我的要求,也就是用一些额外的逻辑来装饰这个转换器。

我如何确保这些值被正确反序列化?

以下代码是我完成这项工作的试用版<然而,这条线

Reader=new JsonTextReader(new StringReader(已清理));

打破了自基以来的整个事情。ReadJson无法将字符串识别为JSON。

有没有更好的方法可以做到这一点,而不必在StringEnumConverter中实现所有现有的逻辑<我怎样才能修正我的方法?

public class BkStringEnumConverter : StringEnumConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.String)
        {
            var enumString = reader.Value.ToString();
            if (enumString.Contains("-"))
            {
                var cleaned = enumString.Split('-').Select(FirstToUpper).Aggregate((a, b) => a + b);
                reader = new JsonTextReader(new StringReader(cleaned));
            }
        }
        return base.ReadJson(reader, objectType, existingValue, serializer);
    }

    private static string FirstToUpper(string input)
    {
        var firstLetter = input.ToCharArray().First().ToString().ToUpper();
        return string.IsNullOrEmpty(input)
            ? input
            : firstLetter + string.Join("", input.ToCharArray().Skip(1));
    }
}

共有3个答案

董联
2023-03-14

这在Json中变得更容易。NET 12.0.1将NamingStrategy添加到StringEnumConverter

新功能-添加了对NamingStrategy到StringENumConzer的支持

还有Json。NET 12.0.3为连字符分隔的烤肉串外壳添加了KebabCaseNamingStrategy,比如一些枚举值

新功能-添加KebabCaseNamingStrategy

使用这种方法,MyEnum不需要任何注释。

具体来说,在12.0.3及更高版本中,当构造转换器并将其添加到JsonSerializerSettings时,可以将KebabCaseNamingStrategy传递到StringEnumConverter的多个构造函数中的任意一个。转换器

var settings = new JsonSerializerSettings
{
    Converters = { new StringEnumConverter(new KebabCaseNamingStrategy()) },
};
var json = JsonConvert.SerializeObject(MyEnum.SomeEnumValue, settings);

Assert.IsTrue(json == "\"some-enum-value\""); // Passes successfully

这样做之后,您的序列化枚举值现在将变成烤羊肉串大小写。这里是演示小提琴#1。

在JsonNET 12.0.1和12.0.2您可以通过子类化SnakeCaseNamingStrategy来定义您自己的kebab案例命名策略:

public class KebabCaseNamingStrategy : SnakeCaseNamingStrategy
{
    protected override string ResolvePropertyName(string name)
    {
        return base.ResolvePropertyName(name).Replace('_', '-');
    }
}

这里是演示小提琴#2。

石苏燕
2023-03-14

您也可以使用以下代码:

[JsonConverter(typeof(StringEnumConverter))]
public enum ResposeStatus
{
    [EnumMember(Value = "success value")]
    Success,
    [EnumMember(Value = "fail value")]
    Fail,
    [EnumMember(Value = "error value")]
    Error
};

当序列化JsonConverts.Seriize(),将使用ENum成员内的文本。

仰翰采
2023-03-14

我通过在枚举值上添加EnumMember属性解决了这个问题。Json。NET defaultStringEnumConverter完美地处理了这些属性。

示例:

public enum MyEnum
{
    [EnumMember(Value = "some-enum-value")]
    SomeEnumValue,
    Value,
    [EnumMember(Value = "some-other-value")]
    SomeOtherValue
}

请注意,如果在枚举中不能使用破折号或其他特殊字符,则只需指定属性。大小写由StringEnumConverter处理。因此,如果服务返回一个类似于someenumvalue的值,那么应该在enumsomeenumvalue中这样使用它。如果您更喜欢SomeEnumValue,则应使用EnumMember属性。如果服务像这样返回someEnumValue,您可以像这样使用someEnumValue(当您使用CamelCaseText属性时,它是现成的)。

您可以在JsonSerializerSettings中轻松指定转换器和其他设置。

以下是我自己使用的设置示例。

new JsonSerializerSettings
{
    ContractResolver = new CamelCasePropertyNamesContractResolver(),
    Converters = new List<JsonConverter> { new StringEnumConverter { CamelCaseText = true } },
    NullValueHandling = NullValueHandling.Ignore
};
 类似资料:
  • 我正在构建一个名为“id”的查询参数,它是一个列表,所以我有类似于localhost:8080/application?id=1 (我知道我的方法不够,我需要写第一个?id=) 方法 我的问题是:为什么我收到这个错误在Collectors.joining(" 我正在使用OpenJDK

  • 问题内容: 如何用“。”格式化数字 作为千位分隔符,和“,”作为MySql中的十进制分隔符? 我正在使用像 SELECT Format(myNumber,2)as myNumberFormatted FROM … 但是返回类型是一个数字,例如: 相反,我想要 在MySQL中怎么做? 谢谢 问题答案: MySQL> = 5.5: MySQL <5.5:

  • 问题内容: 我正在使用一个API,它返回这样的字符串值。 我尝试将这些值放在一个枚举中,因为默认的StringEnumConverter不能完成工作,因此我尝试使用一些附加逻辑来装饰此Converter。如何确保正确反序列化了这些值? 以下代码是我完成此工作的尝试。然而,由于base.ReadJson无法将字符串识别为JSON,所以这行打破了整个事情。 是否有更好的方法可以执行此操作而不必在Str

  • 我想把这个字典变成这样的制表符分隔文件: 我应该如何做到这一点。谢啦

  • 问题内容: 什么正则表达式模式需要我传递给 拆分成字符串使用的所有空格字符(子字符串数组,等)作为分隔符? 问题答案: 某些东西 这会将所有空白分组为分隔符。 因此,如果我有字符串: 这将产生字符串并省略和之间的空白。 正如VonC指出的那样,应该转义反斜杠,因为Java首先会尝试将字符串转义为特殊字符,然后将其发送给解析。你想要的是字面量,这意味着你需要通过。可能会造成一些混乱。 在相当于。

  • 问题内容: 在大量的Unicode字符中,有一些实际上代表多个字符,例如U + FB00连字ff表示两个’f’字符。有什么容易的方法可以将这样的字符转换成多个单个字符?最好是在标准Java API中可用的东西,但是如果需要,我可以引用一个外部库。 问题答案: U + FB00是兼容字符。通常,Unicode不支持连字的单独代码点(认为是否使用连字以及何时使用连字是布局决定,并且不影响数据的存储方式)