msgpack-cli
msgpack-cli copied to clipboard
EnumMemberAttribute does not work. (expectedly)
Hi, we want to use MessagePack in our production and ran into a problem. Current stable version does not work with EnumMemberAttribute. It's important for us. I've wrote some tests for example
public class Tests
{
[Fact]
public void Failed()
{
// arrange
// act
var firstDto = new DtoWithFirstEnum {Enum = FirstEnum.NotOk};
var serializerForFirst = MessagePackSerializer.Get<DtoWithFirstEnum>();
var bytes = serializerForFirst.PackSingleObject(firstDto);
var serializerForSecond = MessagePackSerializer.Get<DtoWithSecondEnum>();
var secondDto = serializerForSecond.UnpackSingleObject(bytes);
// assert
Assert.Equal(SecondEnum.SecondValue, secondDto.Enum);
}
[Fact]
public void Pass()
{
// arrange
// act
var firstDto = new DtoWithFirstEnum {Enum = FirstEnum.NotOk};
var json = JsonConvert.SerializeObject(firstDto);
var secondDto = JsonConvert.DeserializeObject<DtoWithSecondEnum>(json);
// assert
Assert.Equal(SecondEnum.SecondValue, secondDto.Enum);
}
}
[DataContract]
public class DtoWithFirstEnum
{
[DataMember(Name = "enum")] public FirstEnum Enum { get; set; }
}
[DataContract]
public class DtoWithSecondEnum
{
[DataMember(Name = "enum")] public SecondEnum Enum { get; set; }
}
public enum FirstEnum
{
[EnumMember(Value = "ok")]
OK,
[EnumMember(Value = "not_ok")]
NotOk
}
public enum SecondEnum
{
[EnumMember(Value = "ok")]
FirstValue,
[EnumMember(Value = "not_ok")]
SecondValue
}
Looks like we can refine the EnumMessagePackSerializer class in ctor and add new value ByEnumMember in EnumSerializationMethod
protected EnumMessagePackSerializer( SerializationContext ownerContext, EnumSerializationMethod serializationMethod )
: base( ownerContext, SerializerCapabilities.PackTo | SerializerCapabilities.UnpackFrom )
{
if ( !typeof( TEnum ).GetIsEnum() )
{
throw new InvalidOperationException(
String.Format( CultureInfo.CurrentCulture, "Type '{0}' is not enum.", typeof( TEnum ) )
);
}
this._serializationMethod = serializationMethod;
this._underlyingType = Enum.GetUnderlyingType( typeof( TEnum ) );
var members = Enum.GetValues( typeof( TEnum ) ) as TEnum[];
this._serializationMapping = new Dictionary<TEnum, string>( members.Length );
this._deserializationMapping = new Dictionary<string, TEnum>( members.Length );
foreach ( var member in members )
{
var enumName = serializationMethod == EnumSerializationMethod.ByEnumMember
? GetNameFromEnumMemberAttr( member )
: member.ToString();
var asString = ownerContext.EnumSerializationOptions.SafeNameTransformer( enumName);
this._serializationMapping[ member ] = asString;
this._deserializationMapping[ asString ] = member;
}
}
Can you suggest a quick way to solve the problem? Thank you.