Reputation: 6666
I'm getting data in json format from different sources and I'm trying to map them to objects implementing the same interface.
The json variable looks something like this from feed 1:
{"identifier": 232, "type": "Feed1"}
And I'm serializing it using this object:
[DataContract]
public class Class A : InterfaceA
{
[DataMember(Name = "identifier")]
public int Id{ get; set; }
[DataMember(Name = "type")]
public FeedType Type { get; set; }
}
[DataContract]
public enum FeedType
{
[EnumMember(Value = "Feed1")]
FeedA,
[EnumMember(Value = "Feed2")]
FeedB,
[EnumMember(Value = "Feed3")]
FeedC
}
The interface looks like this:
public interface InterfaceA
{
int Id {get;set;}
FeedType Type{get;set;}
}
In feed 2, the object looks like this:
{"identifier": 232, "feedType": "A"}
How can I create another object that implements the same interface and will return the same enum? How do I set up the DataContract?
EDIT:
I serialize it like this
var serializer = new DataContractJsonSerializer(ClassA);
var ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
var serializedObject = serializer.ReadObject(ms);
Upvotes: 0
Views: 632
Reputation: 29674
so if you want a class B
[DataContract]
public class ClassB : InterfaceA
{
[DataMember(Name = "identifier")]
public int Id{ get; set; }
[DataMember(Name = "type")]
public FeedType Type { get; set; }
}
var serializer = new DataContractJsonSerializer(ClassB);
var ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
var serializedObject = serializer.ReadObject(ms);
Thats it?! you could use a generic if you wanted to reuse the code:
public T SerialiseObject<T>(string json) where T : InterfaceA
{
var serializer = new DataContractJsonSerializer(T);
var ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
return (T)serializer.ReadObject(ms);
}
then call it:
SerialiseObject<ClassA>(json);
SerialiseObject<ClassB>(json);
to explain more fully you could not have
public class ClassA : InterfaceA
{
public ns1.FeedType Type{get; set;}
}
and
public class ClassB : InterfaceA
{
public ns2.FeedType Type{get; set;}
}
this would not compile as InterfaceA
would expect either ns1.FeedType
or ns2.FeedType
Upvotes: 0
Reputation: 116108
I'll give an answer using Json.Net (of course if you are open to use a different serializer)
string json = @"{""identifier"": 232, ""type"": ""Feed2""}";
var classa = JsonConvert.DeserializeObject<ClassA>(json);
.
public interface InterfaceA
{
int Id { get; set; }
FeedType Type { get; set; }
}
public class ClassA : InterfaceA
{
[JsonProperty("identifier")]
public int Id{ get; set; }
[JsonConverter(typeof(MyConverter))] //<--- !!!
[JsonProperty("type")]
public FeedType Type { get; set; }
}
[DataContract]
public enum FeedType
{
[EnumMember(Value = "Feed1")]
FeedA,
[EnumMember(Value = "Feed2")]
FeedB,
[EnumMember(Value = "Feed3")]
FeedC
}
And this is the type converter class
public class MyConverter : Newtonsoft.Json.Converters.StringEnumConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(FeedType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var field = objectType.GetFields()
.First(f => f.GetCustomAttributes(false)
.Any(a=>a.GetType()==typeof(EnumMemberAttribute) &&
((EnumMemberAttribute)a).Value.Equals(reader.Value)));
return field.GetValue(null);
}
}
Upvotes: 1