I\'m consuming an api which returns string values like this. some-enum-value
I try to put these values in an enum, since the default StringEnumConverter
Also u can use this methods:
public static string GetDescription(this Enum member)
{
if (member.GetType().IsEnum == false)
throw new ArgumentOutOfRangeException(nameof(member), "member is not enum");
var fieldInfo = member.GetType().GetField(member.ToString());
if (fieldInfo == null)
return null;
var attributes = fieldInfo.GetCustomAttributes<DescriptionAttribute>(false).ToList();
return attributes.Any() ? attributes.FirstOrDefault()?.Description : member.ToString();
}
or
public static string GetDescription(this object member)
{
var type = member.GetType();
var attributes = type.GetCustomAttributes<DescriptionAttribute>(false).ToList();
return attributes.Any() ? attributes.FirstOrDefault()?.Description : member.GetType().Name;
}
and enum should have desctription attribute. Like this:
public enum MyEnum
{
[Description("some-enum-value")]
And,
[Description("some-enum-value")]
Or
}
And than you can use your enum
like this:
MyEnum.GetDescription(); //return "some-enum-value"
This has been made easier in Json.NET 12.0.1 with the addition of NamingStrategy to StringEnumConverter:
New feature - Added support for NamingStrategy to StringEnumConverter
And Json.NET 12.0.3 adds KebabCaseNamingStrategy for hyphen-separated kebab casing like some-enum-value
:
New feature - Added KebabCaseNamingStrategy
No annotations at all are required for MyEnum
with this approach.
Specifically, in 12.0.3 and later you can pass KebabCaseNamingStrategy
into any of several of the constructors for StringEnumConverter
when constructing and adding converters to JsonSerializerSettings.Converters:
var settings = new JsonSerializerSettings
{
Converters = { new StringEnumConverter(new KebabCaseNamingStrategy()) },
};
var json = JsonConvert.SerializeObject(MyEnum.SomeEnumValue, settings);
Assert.IsTrue(json == "\"some-enum-value\""); // Passes successfully
Having done so, your serialized enum values will now be kebab-cased. Demo fiddle #1 here.
In Json.NET 12.0.1 and 12.0.2 you can define your own kebab case naming strategy by subclassing SnakeCaseNamingStrategy:
public class KebabCaseNamingStrategy : SnakeCaseNamingStrategy
{
protected override string ResolvePropertyName(string name)
{
return base.ResolvePropertyName(name).Replace('_', '-');
}
}
Demo fiddle #2 here.
I solved the issue by adding EnumMember attributes on my enum values. The Json.NET default StringEnumConverter
perfectly deals with these attributes.
Example:
public enum MyEnum
{
[EnumMember(Value = "some-enum-value")]
SomeEnumValue,
Value,
[EnumMember(Value = "some-other-value")]
SomeOtherValue
}
Please note that you only have to specify the attributes in case of dashes or other special chars you can't use in your enum. The uppercase lowercase is dealt with by the StringEnumConverter
. So if the service returns a value like someenumvalue
you should use it like this in the enum Someenumvalue
. If you prefer SomeEnumValue
you should use the EnumMember
attribute. In case the service returns it like this someEnumValue
you can just use it like this SomeEnumValue
(It works out of the box when you use the CamelCaseText property).
You can easily specify your converters and other settings in the JsonSerializerSettings
.
Here is an example of the settings I use myself.
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Converters = new List<JsonConverter> { new StringEnumConverter { CamelCaseText = true } },
NullValueHandling = NullValueHandling.Ignore
};
You can also use this code:
[JsonConverter(typeof(StringEnumConverter))]
public enum ResposeStatus
{
[EnumMember(Value = "success value")]
Success,
[EnumMember(Value = "fail value")]
Fail,
[EnumMember(Value = "error value")]
Error
};
When serializing JsonConvert.Serialize()
, will use the text inside the EnumMember
.