JSON.NET serialization - how is the default comparison with ReRequireResolver?

I am using JSON.NET 6.0.3. I changed the PreserveReferences parameter as follows:

HttpConfiguration.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;

My object graph resembles the following:

public class CarFromManufacturer
{
    public int CarID { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    public CarManufacturer Manufacturer { get; set; }
}

public class CarManufacturer
{
    public int ManufacturerID { get; set; }
    public string Name { get; set; }
}

My WebAPI controller returns an IEnumerable [CarFromManufacturer] result set. Thus, the result may be a list of 5 cars from two unique manufacturers. I expect that the JSON result will list each manufacturer only after full serialization, and then subsequent use of the same manufacturer as $ ref ID, to the original $ id. This is not happening.

Even if I can't find any documentation that talks about how equality is set for the ReferenceResolver, I implemented IEquatable along with overriding base.Equals and base.GetHashCode () without any luck.

IReferenceResolver, , .

, , , factory , , CarFromManufacturer, CarManufacturer... CarManufacturer. , , IEquatable base.Equals(object) base.GetHashCode().

DefaultReferenceResolver default constructor BidirectionalDictionary, EqualityComparer.Default, MSDN T IEquatable, , T base.Equals().... , IEquatable CarManufacturer . CarManufacturer.Equals() GethashCode() ..

+4
2

JSON.NET , .

-, IReferenceResolver.

, IEqualityComparer<T> :

public class ReferenceResolver<T> : IReferenceResolver
{
    private Dictionary<string, T> stringToReference;
    private Dictionary<T, string> referenceToString;

    private int referenceCount;

    public ReferenceResolver(IEqualityComparer<T> comparer)
    {
        this.stringToReference = new Dictionary<string, T>();
        this.referenceToString = new Dictionary<T, string>(comparer);
        this.referenceCount = 0;
    }

    public void AddReference(
        object context,
        string reference,
        object value)
    {
        this.referenceToString.Add((T)value, reference);
        this.stringToReference.Add(reference, (T)value);
    }

    public string GetReference(
        object context,
        object value)
    {
        string result = null;

        if (!this.referenceToString.TryGetValue((T)value, out result))
        {
            referenceCount++;
            result = referenceCount.ToString(CultureInfo.InvariantCulture);

            this.referenceToString.Add((T)value, result);
            this.stringToReference.Add(result, (T)value);
        }

        return result;
    }

    public bool IsReferenced(
        object context,
        object value)
    {
        return this.referenceToString.ContainsKey((T)value);
    }

    public object ResolveReference(
        object context,
        string reference)
    {
        T r = default(T);

        this.stringToReference.TryGetValue(reference, out r);
        return r;
    }
}
+2

Json.Net Equals . , , , , . , , Equals .

. , , :

var settings = new JsonSerializerSettings
                           {
                               EqualityComparer = new DefaultEqualityComparer(),
                           };

public class DefaultEqualityComparer : IEqualityComparer
    {
        public bool Equals(object x, object y)
        {
            return ReferenceEquals(x, y);
        }

        public int GetHashCode(object obj)
        {
            return obj.GetHashCode();
        }
    }
+1

All Articles