How to prevent calling a property for the second time, while using the same object inside with "this" clause

95 views Asked by At

I have a class structure which has few string properties, and I want to add another property that returns the Json string value of the very same object dynamically.

My problem is, when I use this while creating the Json result, it calls the object again recursively, and crashes with StackOverflowException at the end.

I tried to change this field with New Introducer() { Id = this.Id } but it caused the same error.

Although I am able to solve it by identifying a bool IsSerializing parameter and bypassing the field for the second time manually, I am looking for a more decent solution.

Is there a command or attribute to prevent compiler from calling Serialized property for the second time? Or am I calling the property in a wrong way in the first place?

Here is my class:

public class Introducer
{
    public Introducer()
    {
        this.Id = 0;
        this.NameSurname = string.Empty;
        this.EmailAddress = string.Empty;
        this.UserCreated = new User();
    }

    public int Id { get; set; }
    private string _NameSurname;
    public string NameSurname { get { return _NameSurname; } set { _NameSurname = value.Trim(); } }
    private string _EmailAddress;
    public string EmailAddress { get { return _EmailAddress; } set { _EmailAddress = value.Trim(); } }
    public DateTime DateCreated { get; set; }
    public User UserCreated { get; set; }

    public string Serialized
    {
        get
        {
            return JsonConvert.SerializeObject(this, Formatting.Indented);
        }
    }
}
3

There are 3 answers

1
jl_ On BEST ANSWER

Here is a sample to try out. Idea is to use JsonIgnore attribute to instruct the serializer to not pick up the property for serialization.

class MyClass
{
    public int Id { get; set; }
    private string _NameSurname;
    public string NameSurname { get { return _NameSurname; } set { _NameSurname = value.Trim(); } }
    private string _EmailAddress;
    public string EmailAddress { get { return _EmailAddress; } set { _EmailAddress = value.Trim(); } }
    public DateTime DateCreated { get; set; }

    [JsonIgnore]
    public string Serialized
    {
        get
        {
            return JsonConvert.SerializeObject(this, Formatting.Indented);
        }
    }
}

Invoke as:

MyClass obj = new MyClass();
var serialized = obj.Serialized;

EDIT:

Good practice 1: As mentioned in other answers, a method could be used instead of the property as below:

class MyClass
{
    public int Id { get; set; }
    private string _NameSurname;
    public string NameSurname { get { return _NameSurname; } set { _NameSurname = value.Trim(); } }
    private string _EmailAddress;
    public string EmailAddress { get { return _EmailAddress; } set { _EmailAddress = value.Trim(); } }
    public DateTime DateCreated { get; set; }

    public string GetJSON()
    {
        return JsonConvert.SerializeObject(this, Formatting.Indented);
    }
}

Good practice 2: Follow the right OOD patterns and let the serialization (or representation) of the object in a format be done in a separate class.

0
bedane On

Use [JsonIgnore] Or better yet, change this into a method

1
BlueMonkMN On

You should not put code like that into a property. Properties are intended (conceptually) for data and only an insignificant complexity of code; certainly not recursive code. Serialization is certainly not insignificant code. If you did want to have a Serialized property that was conceptually appropriate, it should contain a cached version of the serialized object rather than actually generating the serialized data. Instead the functionality for generating the serialized representation of the object should be in a method, not a property.