0

I'm having trouble understanding serialization of one of my objects.

Scenario:

I'm receiving data from a service which is in a given format. I want to take the data in as is. Due to naming conventions I have to use DataMember properties to match the incoming data to properly named class properties. I use System.Runtime.Serialization for this. Example:

[DataContract]
public class IncomingData
{
    [DataMember(Name = "$Filename")]
    public string Filename { get; set; }
}

This works fine and the data is mapped to the internal property name. At some point I have to serialize this object again and I naively thought that it would serialize to the internal property name e.g.

{ "Filename":"C:\temp\lala.txt"} 

however that is not true and the original propertyname "$Filename" is used instead. I assume this is because DataMember works both ways.

Is there an elegant way to have this object serialize to the propertynames and ignore DataMember? I tried if using a different serialization library works (JSON.NET) but it also seems to follow DataMember.

Do I have to wrap this object to another to acchieve? Thanks for any hints! blu

blu
  • 55
  • 5
  • Normally it shouldn't matter... When you 'serialize again', who/what is the consumer then? – bommelding Sep 11 '18 at 08:40
  • Thanks. The application takes that input, and based on some logic, re-routes it to some other service. In theory I could hand it over as is, but since many of the incoming names are not so easy to read, I was keen on handing over a more comprehensible object with the same data. The receiving service will have to deal with whatever I deliver, so technically it isnt a necessity. – blu Sep 11 '18 at 10:41
  • The ivory tower answer is that you shouldn't use the same class for two different connections. That makes a tight coupling and invites versioning issues. So consider converting it to another class at some point. – bommelding Sep 11 '18 at 12:39
  • Related (but maybe not duplicate): [Configure JSON.NET to ignore DataContract/DataMember attributes](https://stackoverflow.com/q/11055225). – dbc Sep 11 '18 at 20:08

1 Answers1

1

You could define an interface for keeping these objects in sync...

public interface IData
{
    string Filename { get; set; }
}

// deserialize me.
[DataContract]
public class IncomingData : IData
{
    [DataMember(Name = "$Filename")]
    public string Filename { get; set; }
}

// serialize me.
public class Data : IData
{
    public string Filename { get; set; }
}

...or you could use virtual properties and override them with the serialization attributes...

// serialize me.
class Data
{
    public virtual string Filename { get; set; }
}

// deserialize me.
[DataContract]
class IncomingData : Data
{
    [DataMember(Name = "$Filename")]
    public override string Filename { get => base.Filename; set => base.Filename = value; }
}

...both of these methods would require the use of a mapper like AutoMapper to clone the IncomingData into the attribute-free Data class...

mapper.Map<IncomingData, Data>(user);

...so I appreciate this feels less than ideal.

Creyke
  • 1,887
  • 2
  • 12
  • 16
  • 1
    Thanks, solution one seems what I had in my head, but properly put into words that make sense ;-). Solution one seems cleaner to me, but the overhead of another class and another dependency with AutoMapper seems quite big. I'll leave this open for a bit, if nothing else comes in I'll accept that as the answer. – blu Sep 11 '18 at 10:43