I created a class that contained another class. Newtonsoft tells me there is a self referencing loop when JsonConvert.SerializeObject(translatedResponse) is called on the object. After trying various things, I changed the namespace name (which was 'DocumentGenerationParticipant', and created a DocumentGenerationParticipantResult for the plural class's List, instead of using the singular version that is also a DTO for a /participant endpoint. That worked, but I don't see why JSON serialization wouldn't work on this, and I see no circular reference? Did I miss something?
Program.CS that uses below DTOs:
using ConsoleApp4.DocumentGeneration;
using ConsoleApp4.DocumentGeneration.DocumentGenerationParticipant;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace ConsoleApp4
{
static class Program
{
static void Main(string[] args)
{
var list = new List<DocumentGenerationParticipantResponse>()
{
new DocumentGenerationParticipantResponse("testName","testEmail","testUri","testRole"),
new DocumentGenerationParticipantResponse("testName","testEmail","testUri","testRole"),
new DocumentGenerationParticipantResponse("testName","testEmail","testUri","testRole")
};
var response = new DocumentGenerationParticipantsResponse(list);
var result = JsonConvert.SerializeObject(response);
Console.WriteLine(result);
}
}
}
DocumentGenerationParticipantResponse:
using System.Collections.Generic;
namespace ConsoleApp4.DocumentGeneration
{
public class DocumentGenerationParticipantResponse
{
public string Name { get; }
public string Email { get; }
public string AccessUri { get; }
public string Role { get; }
public DocumentGenerationParticipantResponse(string name, string email, string accessUri, string role)
{
this.Name = name;
this.Email = email;
this.AccessUri = accessUri;
this.Role = role;
}
public override bool Equals(object obj)
{
if (obj is null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
DocumentGenerationParticipantResponse tmp = (DocumentGenerationParticipantResponse)obj;
return Equals(this.Name, tmp.Name) &&
Equals(this.Email, tmp.Email) &&
Equals(this.AccessUri, tmp.AccessUri) &&
Equals(this.Role, tmp.Role);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = -2099;
hashCode = hashCode * -2399 + EqualityComparer<string>.Default.GetHashCode(Name);
hashCode = hashCode * -2399 + EqualityComparer<string>.Default.GetHashCode(Email);
hashCode = hashCode * -2399 + EqualityComparer<string>.Default.GetHashCode(AccessUri);
hashCode = hashCode * -2399 + EqualityComparer<string>.Default.GetHashCode(Role);
return hashCode;
}
}
}
}
DocumentGenerationParticipantsResponse:
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp4.DocumentGeneration.DocumentGenerationParticipant
{
public class DocumentGenerationParticipantsResponse
{
public List<DocumentGenerationParticipantResponse> Participants { get; }
public DocumentGenerationParticipantsResponse(List<DocumentGenerationParticipantResponse> participants)
{
Participants = participants;
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (!(obj is List<DocumentGenerationParticipantResponse> list))
{
return false;
}
if (list.Count != this.Participants.Count)
{
return false;
}
return this.Participants.SequenceEqual(list);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = -2099;
this.Participants.ForEach(x => hashCode = hashCode * x.GetHashCode());
return hashCode;
}
}
}
}
Error Message: "Message": "An error has occurred.", "ExceptionMessage": "Self referencing loop detected for property 'Participants' with type 'System.Collections.Generic.List`1[XXXXXX.Api.Management.Contracts.DocumentGeneration.DocumentGenerationParticipantResponse]'. Path ''.",