7

Sometimes, perhaps in a DDD situation, you might want to use C# to create Value Objects to represent data, to give more meaning to your domain than using primitive types would, with the added benefit of being immutable.

For example:

public class PostalCode // Bit like a zipcode
{
    public string Value { get; private set; }

    public PostalCode(string value)
    {
        Value = value;
    }

    // Maybe sprinkle some ToString()/Equals() overrides here
}

Bravo. Well done me.

The only thing is, when serialised to Json, you get this:

{
    "Value": "W1 AJX"
}

That sort of looks okay, but when it's used as a property of an object (let's say an address) then it looks like this:

{
  "Line1": "Line1",
  "Line2": "Line2",
  "Line3": "Line3",
  "Town": "Town",
  "County": "County",
  "PostalCode": {
    "Value": "W1 AJX"
  }
}

Taken to an extreme, you can see there's a lot of noise here. What I'd like to do, is tell Newtonsoft.Json, that when it sees a type of PostalCode, that it can serialise it to a string value (and vice versa). That would result in the following json:

{
  "Line1": "Line1",
  "Line2": "Line2",
  "Line3": "Line3",
  "Town": "Town",
  "County": "County",
  "PostalCode": "W1 AJX"
}

Is this achievable? I've had a look through the docs and I suspect a custom JsonConverter might be the way forward?

Neil Barnwell
  • 41,080
  • 29
  • 148
  • 220
  • 1
    I answered in the "duplicate" question, https://stackoverflow.com/a/48005782/442459. I don't believe these questions are completely the same. But the answer has a generic way to solve the issue. – Lejdholt Dec 28 '17 at 10:37
  • See also my answer in the "duplicate" question, using reflection: https://stackoverflow.com/a/52333106/20444 – activout.se Sep 14 '18 at 13:36

2 Answers2

1
public class PostalCode // Bit like a zipcode
{
    [JsonProperty(PropertyName = "PostalCode")]
    public string Value { get; set; }

    // Maybe sprinkle some ToString()/Equals() overrides here
}

I think this is your answer?

TobiasB
  • 161
  • 1
  • 10
  • 2
    It's a good answer, certainly. Although I would rather avoid sprinkling json.net attributes over classes that, technically speaking, are unaware of such things as serialisation. Attributes used like this are basically a leaky abstraction, though I appreciate the simplicity of this answer. – Neil Barnwell May 04 '17 at 12:33
-2

Could you leverage the implicit operator syntax?

https://msdn.microsoft.com/en-us/library/z5z9kes2.aspx

public class PostalCode
{
     public string Value { get; private set; }

     public PostalCode(string value)
     {
         this.Value = value;
     }

     public static implicit operator string(PostalCode result)
     {
         return result.Value;
     }
 }


var postCode = new PostalCode("WN11 2PZ");
Console.Output(postCode);  // "WN11 2PZ"

I haven't tested this so I could be way off!

Tom
  • 2,321
  • 2
  • 18
  • 29
  • How does this change the behavior of the Newtonsoft JSON serializer? – rene May 04 '17 at 11:13
  • It doesn't, but it may cause the serializer to return the post code string rather than a new object. – Tom May 04 '17 at 11:13