JavaScriptSerializer - JSON serialization of enum as string
No there is no special attribute you can use. JavaScriptSerializer
serializes enums
to their numeric values and not their string representation. You would need to use custom serialization to serialize the enum
as its name instead of numeric value.
If you can use JSON.Net instead of JavaScriptSerializer
than see answer on this question provided by OmerBakhari: JSON.net covers this use case (via the attribute [JsonConverter(typeof(StringEnumConverter))]
) and many others not handled by the built in .net serializers. Here is a link comparing features and functionalities of the serializers.
Serialize enum to string
The JSON formatter has very specialized behaviour when working with enumerations; the normal Data Contract attributes are ignored and it treats your enum as a number, not the more human-readable string you'd expect with other formats. Whilst this makes it easy to deal with flag-type enumerations, it makes most other types much harder to work with.
From MSDN:
Enumeration member values are treated as numbers in JSON, which is
different from how they are treated in data contracts, where they are
included as member names. For more information about the data contract
treatment, see Enumeration Types in Data Contracts.
For example, if you have
public enum Color {red, green, blue, yellow,
, serializing yellow produces the number 3 and not the string
pink}
"yellow".All enum members are serializable. The EnumMemberAttribute and the
NonSerializedAttribute attributes are ignored if used.It is possible to deserialize a nonexistent enum value - for example,
the value 87 can be deserialized into the previous Color enum even
though there is no corresponding color name defined.A flags enum is not special and is treated the same as any other enum.
The only practical way to resolve this, to allow end-users to specify a string instead of a number, is to not use the enum in your contract. Instead the practical answer is to replace your enum with a string and perform internal validation on the value such that it can be parsed into one of the valid enum representations.
Alternatively (though not for the feint of heart), you could replace the JSON formatter with your own, which would respect enumerations in the same way as other formatters.
Are there any attributes for serializing Enums as strings in Json.NET?
Just use StringEnumConverter
var actual = json.ToString(Formatting.None,
new Newtonsoft.Json.Converters.StringEnumConverter());
EDIT
Is there no way to tell it to automatically use that converter every time you call ToString()?
JsonConvert.DefaultSettings = () => new JsonSerializerSettings() {
Converters = new List<Newtonsoft.Json.JsonConverter>() { new Newtonsoft.Json.Converters.StringEnumConverter() }
};
var actual = JsonConvert.SerializeObject(json);
Serializing enum values in JSON (C#)
Please take look at JSON serialization of enum as string in stack overflow.
No there is no special attribute you can use. JavaScriptSerializer serializes enums to their numeric values and not their string representation. You would need to use custom serialization to serialize the enum as its name instead of numeric value.
Trying to convert enum to custom string name with JsonStringEnumConverter
By default, it is not supported with System.Text.Json
. You can see the request for the same.
https://github.com/dotnet/runtime/issues/31081
But there is an extension library called 'Macross.Json.Extensions' where you can use JsonStringEnumMemberConverter
attribute and then do what you need.
JsonConverter(typeof(JsonStringEnumMemberConverter))]
public enum DefinitionType
{
[EnumMember(Value = "UNKNOWN_DEFINITION_000")]
DefinitionUnknown
}
[TestMethod]
public void ExampleTest()
{
string Json = JonSerializer.Serialize(DefinitionType.DefinitionUnknown);
Assert.AreEqual("\"UNKNOWN_DEFINITION_000\"", Json);
DefinitionType ParsedDefinitionType = JsonSerializer.Deserialize<DefinitionType>(Json);
Assert.AreEqual(DefinitionType.DefinitionUnknown, ParsedDefinitionType);
}
You can see more at - https://github.com/Macross-Software/core/tree/develop/ClassLibraries/Macross.Json.Extensions#enumerations
Deserialise Enum From JSON String with Spaces
This is a solution for System.Text.Json
I used the Nuget package System.Text.Json.EnumExtensions
https://github.com/StefH/System.Text.Json.EnumExtensions
// you probably want these options somewhere global
private JsonSerializerOptions options;
private class TestEnumWrapper<T> where T : struct
{
public T TestEnum { get; set; }
}
public enum ObjectClass
{
[EnumMember(Value = "Rocket Body")]
RocketBody,
[EnumMember(Value = "Rocket Debris")]
RocketDebris,
[EnumMember(Value = "Rocket Fragmentation Debris")]
RocketFragmentationDebris,
[EnumMember(Value = "Rocket Mission Related Object")]
RocketMissionRelatedObject,
//etc...
}
private void CanDeserialiseEnumsWithCustomJsonStrings(Enum expected, string jsonName)
{
var json = $"{{\"TestEnum\":\"{jsonName}\"}}";
Type constructed = typeof(TestEnumWrapper<>).MakeGenericType(expected.GetType());
var res = JsonSerializer.Deserialize(json, constructed, options);
}
public void Test()
{
this.options = new JsonSerializerOptions();
options.Converters.Add(new JsonStringEnumConverterWithAttributeSupport());
var testSerialize = JsonSerializer.Serialize(new TestEnumWrapper<ObjectClass>()
{ TestEnum = ObjectClass.RocketBody }, options);
// Test Deserialize
CanDeserialiseEnumsWithCustomJsonStrings(ObjectClass.RocketBody, "Rocket Body");
}
You only have to add the new JsonStringEnumConverterWithAttributeSupport()
to the JsonSerializerOptions.Converters
for this to work.
If you want to use the Converter as an Attribute you have to add an parameterless constructor to the class JsonStringEnumConverterWithAttributeSupport
public JsonStringEnumConverterWithAttributeSupport() : this(namingPolicy : null, allowIntegerValues : true,
parseEnumMemberAttribute : true, parseDisplayAttribute : false, parseDescriptionAttribute : false)
{
}
Related Topics
Multiple Levels in MVC Custom Routing
Does Json.Net Cache Types' Serialization Information
Remove Duplicates in the List Using Linq
Why Does Property Set Throw Stackoverflow Exception
How to Modify a List in a 'Foreach' Loop
Understanding Events and Event Handlers in C#
Select Tag Helper in ASP.NET Core MVC
Why Is There a Default Instance of Every Form in Vb.Net But Not in C#
Given a Datetime Object, How to Get an Iso 8601 Date in String Format
Parallel Foreach With Asynchronous Lambda
What Is the Yield Keyword Used For in C#
In .Net, Which Loop Runs Faster, 'For' or 'Foreach'
How to Prevent the App from Terminating When I Close the Startup Form
Best Practice to Call Configureawait For All Server-Side Code