mSwierkot
mSwierkot

Reputation: 45

Displaying list of foreign key values Asp Net Web Api

JsonError

Working on my Gym managment application I've encountered with displaying collection of data related to Client model.

The problem is related to following models:

public class Client
{
    [Key]
    public int Id { get; set; }

    public int CardId { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Phone { get; set; }
    public string Email { get; set; }

    public string PersonalInfo => "ID: " + CardId + ": " + Name + " " + Surname;

    public int? GymEntries { get; set; }
    public int? MartialArtsEntries { get; set; }

    public int? GymEntriesLeft { get; set; }
    public int? MartialArtsEntriesLeft { get; set; }

    public DateTime? ClientJoined { get; set; }
    public DateTime? SubscriptionExpires { get; set; }

    public int? SubscriptionId { get; set; }
    public virtual Subscription Subscription { get; set; }

    public bool? IsDeleted { get; set; }

    public virtual ICollection<Payment> Payments { get; set; }
}


public class Payment
{
    [Key]
    public int Id { get; set; }

    public int ClientId { get; set; }
    public virtual Client Client { get; set; }

    public int? SubscriptionId { get; set; }
    public virtual Subscription Subscription { get; set; }

    public int CashRegistered { get; set; }
    public string AdditionalInformation { get; set; }

    public DateTime? PaymentRegistered { get; set; }
    public DateTime? SubscriptionExpires { get; set; }

}

Everything works fine, until I want my Client controller, when given get/id request, to return all Client data including all payments related to client id from Payment. Json result in Postman doesn't return proper format, it misses payments list.

That's the way I try to do that in my Controller

[HttpGet("{id}")]
public async Task<ActionResult<Client>> GetClient(int id)
{
   var client = await _context.Client.FindAsync(id);
   var subscription = await _context.Subscription.FindAsync(client.SubscriptionId); 
   var payments = await _context.Payment.Where(p => p.Client == client).ToListAsync();

   client.Subscription = subscription;
   client.Payments = payments;

   if (client == null)
   {
       return NotFound();
   }

   if (client.IsDeleted == true)
   {
       return NotFound();
   }

   return client;
}

Upvotes: 0

Views: 1178

Answers (1)

Stanislav
Stanislav

Reputation: 213

Try that:

var payments = await _context.Payment.Where(p => p.ClientId == client.Id).ToListAsync();

You should use your Id's to select entities but not entire entities.

UPD:

Try to set attribute [JsonIgnore] on public virtual Client Client { get; set; } in your Payment class. To prevent json serializer from endless loop.

Also you can stop Self referencing loop due to the proxies while you converting the entity to JSON as follows:

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddMvc()
        .AddJsonOptions(
            options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
        );

    ...
}

Upvotes: 2

Related Questions