Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit bf2696f

Browse files
committed
Add support for custom values with [EnumMember]
1 parent 111a9b8 commit bf2696f

File tree

6 files changed

+86
-3
lines changed

6 files changed

+86
-3
lines changed

src/ServiceStack.Text/Common/ITypeSerializer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public interface ITypeSerializer
5454
void WriteDecimal(TextWriter writer, object decimalValue);
5555
void WriteEnum(TextWriter writer, object enumValue);
5656
void WriteEnumFlags(TextWriter writer, object enumFlagValue);
57+
void WriteEnumMember(TextWriter writer, object enumFlagValue);
5758

5859
//object EncodeMapKey(object value);
5960

src/ServiceStack.Text/Common/JsWriter.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using System.IO;
55
using System.Runtime.CompilerServices;
6+
using System.Runtime.Serialization;
67
using ServiceStack.Text.Json;
78
using ServiceStack.Text.Jsv;
89

@@ -282,9 +283,13 @@ public WriteObjectDelegate GetValueTypeToStringMethod(Type type)
282283
else
283284
{
284285
if (underlyingType.IsEnum)
285-
return type.FirstAttribute<FlagsAttribute>() != null
286-
? (WriteObjectDelegate)Serializer.WriteEnumFlags
287-
: Serializer.WriteEnum;
286+
{
287+
if (type.HasAttribute<DataContractAttribute>())
288+
return Serializer.WriteEnumMember;
289+
if (type.HasAttribute<FlagsAttribute>())
290+
return Serializer.WriteEnumFlags;
291+
return Serializer.WriteEnum;
292+
}
288293
}
289294

290295
if (type.HasInterface(typeof(IFormattable)))

src/ServiceStack.Text/Common/ParseUtils.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
//
1212

1313
using System;
14+
using System.Runtime.CompilerServices;
15+
using System.Runtime.Serialization;
1416

1517
namespace ServiceStack.Text.Common
1618
{
@@ -69,6 +71,21 @@ public static object TryParseEnum(Type enumType, string str)
6971
str = str.Replace("_", "");
7072
}
7173

74+
if (enumType.HasAttribute<DataContractAttribute>())
75+
{
76+
var enumNames = Enum.GetNames(enumType);
77+
var enumValues = Enum.GetValues(enumType);
78+
var i = 0;
79+
foreach (var enumValue in enumValues)
80+
{
81+
var enumName = enumNames[i++];
82+
var mi = enumType.GetMember(enumName)[0];
83+
var useValue = mi.FirstAttribute<EnumMemberAttribute>()?.Value ?? enumValue;
84+
if (string.Equals(str, useValue.ToString(), StringComparison.OrdinalIgnoreCase))
85+
return enumValue;
86+
}
87+
}
88+
7289
return Enum.Parse(enumType, str, ignoreCase: true);
7390
}
7491
}

src/ServiceStack.Text/Json/JsonTypeSerializer.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Globalization;
66
using System.IO;
77
using System.Runtime.CompilerServices;
8+
using System.Runtime.Serialization;
89
using System.Text;
910
using ServiceStack.Text.Common;
1011
using ServiceStack.Text.Pools;
@@ -298,6 +299,17 @@ public void WriteEnumFlags(TextWriter writer, object enumFlagValue)
298299
JsWriter.WriteEnumFlags(writer, enumFlagValue);
299300
}
300301

302+
public void WriteEnumMember(TextWriter writer, object enumValue)
303+
{
304+
if (enumValue == null) return;
305+
306+
var enumType = enumValue.GetType();
307+
var mi = enumType.GetMember(enumValue.ToString());
308+
var enumMemberAttr = mi[0].FirstAttribute<EnumMemberAttribute>();
309+
var useValue = enumMemberAttr?.Value ?? enumValue;
310+
WriteRawString(writer, useValue.ToString());
311+
}
312+
301313
public ParseStringDelegate GetParseFn<T>()
302314
{
303315
return JsonReader.Instance.GetParseFn<T>();

src/ServiceStack.Text/Jsv/JsvTypeSerializer.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Globalization;
66
using System.IO;
7+
using System.Runtime.Serialization;
78
using ServiceStack.Text.Common;
89
using ServiceStack.Text.Json;
910
#if NETSTANDARD2_0
@@ -255,6 +256,17 @@ public void WriteEnumFlags(TextWriter writer, object enumFlagValue)
255256
JsWriter.WriteEnumFlags(writer, enumFlagValue);
256257
}
257258

259+
public void WriteEnumMember(TextWriter writer, object enumValue)
260+
{
261+
if (enumValue == null) return;
262+
263+
var enumType = enumValue.GetType();
264+
var mi = enumType.GetMember(enumValue.ToString());
265+
var enumMemberAttr = mi[0].FirstAttribute<EnumMemberAttribute>();
266+
var useValue = enumMemberAttr?.Value ?? enumValue;
267+
writer.Write(enumValue.ToString());
268+
}
269+
258270
public object EncodeMapKey(object value)
259271
{
260272
return value;

tests/ServiceStack.Text.Tests/EnumTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,42 @@ public void Does_write_EnumValues_when_ExcludeDefaultValues()
206206
}.ToJson(), Is.EqualTo("{}"));
207207
}
208208
}
209+
210+
[DataContract]
211+
public enum Day
212+
{
213+
[EnumMember(Value = "MON")]
214+
Monday,
215+
[EnumMember(Value = "TUE")]
216+
Tuesday,
217+
[EnumMember(Value = "WED")]
218+
Wednesday,
219+
[EnumMember(Value = "THU")]
220+
Thursday,
221+
[EnumMember(Value = "FRI")]
222+
Friday,
223+
[EnumMember(Value = "SAT")]
224+
Saturday,
225+
[EnumMember(Value = "SUN")]
226+
Sunday,
227+
}
228+
229+
class EnumMemberDto
230+
{
231+
public Day Day { get; set; }
232+
}
233+
234+
[Test]
235+
public void Does_serialize_EnumMember_Value()
236+
{
237+
var dto = new EnumMemberDto {Day = Day.Sunday};
238+
var json = dto.ToJson();
239+
240+
Assert.That(json, Is.EqualTo("{\"Day\":\"SUN\"}"));
241+
242+
var fromDto = json.FromJson<EnumMemberDto>();
243+
Assert.That(fromDto.Day, Is.EqualTo(Day.Sunday));
244+
}
209245

210246
}
211247
}

0 commit comments

Comments
 (0)