2
// Copyright (c) 2007 James Newton-King
4
// Permission is hereby granted, free of charge, to any person
5
// obtaining a copy of this software and associated documentation
6
// files (the "Software"), to deal in the Software without
7
// restriction, including without limitation the rights to use,
8
// copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the
10
// Software is furnished to do so, subject to the following
13
// The above copyright notice and this permission notice shall be
14
// included in all copies or substantial portions of the Software.
16
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
// OTHER DEALINGS IN THE SOFTWARE.
27
using System.Globalization;
28
using Newtonsoft.Json.Utilities;
30
namespace Newtonsoft.Json.Converters
33
/// Converts an <see cref="Enum"/> to and from its name string value.
35
public class StringEnumConverter : JsonConverter
39
/// Writes the JSON representation of the object.
41
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
42
/// <param name="value">The value.</param>
43
/// <param name="serializer">The calling serializer.</param>
44
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
52
Enum e = (Enum) value;
53
string enumName = e.ToString("G");
55
if (char.IsNumber(enumName[0]) || enumName[0] == '-')
56
writer.WriteValue(value);
58
writer.WriteValue(enumName);
62
/// Reads the JSON representation of the object.
64
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
65
/// <param name="objectType">Type of the object.</param>
66
/// <param name="existingValue">The existing value of object being read.</param>
67
/// <param name="serializer">The calling serializer.</param>
68
/// <returns>The object value.</returns>
69
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
71
Type t = (ReflectionUtils.IsNullableType(objectType))
72
? Nullable.GetUnderlyingType(objectType)
75
if (reader.TokenType == JsonToken.Null)
77
if (!ReflectionUtils.IsNullableType(objectType))
78
throw new Exception("Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
83
if (reader.TokenType == JsonToken.String)
84
return Enum.Parse(t, reader.Value.ToString(), true);
86
if (reader.TokenType == JsonToken.Integer)
87
return ConvertUtils.ConvertOrCast(reader.Value, CultureInfo.InvariantCulture, t);
89
throw new Exception("Unexpected token when parsing enum. Expected String or Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
93
/// Determines whether this instance can convert the specified object type.
95
/// <param name="objectType">Type of the object.</param>
97
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
99
public override bool CanConvert(Type objectType)
101
Type t = (ReflectionUtils.IsNullableType(objectType))
102
? Nullable.GetUnderlyingType(objectType)
2
// Copyright (c) 2007 James Newton-King
4
// Permission is hereby granted, free of charge, to any person
5
// obtaining a copy of this software and associated documentation
6
// files (the "Software"), to deal in the Software without
7
// restriction, including without limitation the rights to use,
8
// copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the
10
// Software is furnished to do so, subject to the following
13
// The above copyright notice and this permission notice shall be
14
// included in all copies or substantial portions of the Software.
16
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
// OTHER DEALINGS IN THE SOFTWARE.
27
using System.Collections.Generic;
28
using System.Globalization;
29
using System.Reflection;
30
using System.Runtime.Serialization;
31
using Newtonsoft.Json.Utilities;
33
using Newtonsoft.Json.Utilities.LinqBridge;
38
namespace Newtonsoft.Json.Converters
41
/// Converts an <see cref="Enum"/> to and from its name string value.
43
public class StringEnumConverter : JsonConverter
45
private readonly Dictionary<Type, BidirectionalDictionary<string, string>> _enumMemberNamesPerType = new Dictionary<Type, BidirectionalDictionary<string, string>>();
48
/// Gets or sets a value indicating whether the written enum text should be camel case.
50
/// <value><c>true</c> if the written enum text will be camel case; otherwise, <c>false</c>.</value>
51
public bool CamelCaseText { get; set; }
54
/// Writes the JSON representation of the object.
56
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
57
/// <param name="value">The value.</param>
58
/// <param name="serializer">The calling serializer.</param>
59
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
69
string enumName = e.ToString("G");
71
if (char.IsNumber(enumName[0]) || enumName[0] == '-')
73
writer.WriteValue(value);
77
BidirectionalDictionary<string, string> map = GetEnumNameMap(e.GetType());
79
string resolvedEnumName;
80
map.TryGetByFirst(enumName, out resolvedEnumName);
81
resolvedEnumName = resolvedEnumName ?? enumName;
85
string[] names = resolvedEnumName.Split(',').Select(item => StringUtils.ToCamelCase(item.Trim())).ToArray();
86
resolvedEnumName = string.Join(", ", names);
89
writer.WriteValue(resolvedEnumName);
94
/// Reads the JSON representation of the object.
96
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
97
/// <param name="objectType">Type of the object.</param>
98
/// <param name="existingValue">The existing value of object being read.</param>
99
/// <param name="serializer">The calling serializer.</param>
100
/// <returns>The object value.</returns>
101
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
103
Type t = (ReflectionUtils.IsNullableType(objectType))
104
? Nullable.GetUnderlyingType(objectType)
107
if (reader.TokenType == JsonToken.Null)
109
if (!ReflectionUtils.IsNullableType(objectType))
110
throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
115
if (reader.TokenType == JsonToken.String)
117
var map = GetEnumNameMap(t);
118
string resolvedEnumName;
119
map.TryGetBySecond(reader.Value.ToString(), out resolvedEnumName);
120
resolvedEnumName = resolvedEnumName ?? reader.Value.ToString();
122
return Enum.Parse(t, resolvedEnumName, true);
125
if (reader.TokenType == JsonToken.Integer)
126
return ConvertUtils.ConvertOrCast(reader.Value, CultureInfo.InvariantCulture, t);
128
throw JsonSerializationException.Create(reader, "Unexpected token when parsing enum. Expected String or Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
132
/// A cached representation of the Enum string representation to respect per Enum field name.
134
/// <param name="t">The type of the Enum.</param>
135
/// <returns>A map of enum field name to either the field name, or the configured enum member name (<see cref="EnumMemberAttribute"/>).</returns>
136
private BidirectionalDictionary<string, string> GetEnumNameMap(Type t)
138
BidirectionalDictionary<string, string> map;
140
if (!_enumMemberNamesPerType.TryGetValue(t, out map))
142
lock (_enumMemberNamesPerType)
144
if (_enumMemberNamesPerType.TryGetValue(t, out map))
147
map = new BidirectionalDictionary<string, string>(
148
StringComparer.OrdinalIgnoreCase,
149
StringComparer.OrdinalIgnoreCase);
151
foreach (FieldInfo f in t.GetFields())
157
n2 = f.GetCustomAttributes(typeof (EnumMemberAttribute), true)
158
.Cast<EnumMemberAttribute>()
159
.Select(a => a.Value)
160
.SingleOrDefault() ?? f.Name;
166
if (map.TryGetBySecond(n2, out s))
168
throw new InvalidOperationException("Enum name '{0}' already exists on enum '{1}'."
169
.FormatWith(CultureInfo.InvariantCulture, n2, t.Name));
175
_enumMemberNamesPerType[t] = map;
183
/// Determines whether this instance can convert the specified object type.
185
/// <param name="objectType">Type of the object.</param>
187
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
189
public override bool CanConvert(Type objectType)
191
Type t = (ReflectionUtils.IsNullableType(objectType))
192
? Nullable.GetUnderlyingType(objectType)
b'\\ No newline at end of file'