Shaker Kamal
Shaker Kamal

Reputation: 109

Returning multiple lists data inside an object in ASP dotnet Core API

I have this consignment Entity Model.

public Guid Id { get; set; }
public DateTime? DateCreated { get; set; }
public DateTime? DateModified { get; set; }
public bool? Deleted { get; set; }
public string Status { get; set; }
public string Services { get; set; }
public string CustomerReference { get; set; }
public string ConsignmentNote { get; set; }
public int? TotalPieces { get; set; }
...
public virtual ICollection<ConsignmentDocument> ConsignmentDocument { get; set; }
public virtual ICollection<ConsignmentLine> ConsignmentLine { get; set; }
public virtual ICollection<Legging> Legging { get; set; }

Now the problem that I am facing while fetching a consignment is that I am not getting any data of ConsignmentLine, Legging, ConsignmentDocument in the response body . I was testing it with only ConsignmentLine first in my Consignments Controller. This is my GetConsignment() controller method.

// GET: api/Consignments
    [HttpGet("{id}")]
    public async Task<ActionResult<Consignment>> GetConsignment(Guid id)
    {
        var consignment = await _context.Consignment.where(c =>c.Id == id)
            .Include(conline => conline.ConsignmentLine)
            .FirstOrDefault();
        return consignment;
    }

My ConsignmentLine.cs is this :

    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public decimal? Length { get; set; }
    public decimal? Width { get; set; }
    public decimal? Height { get; set; }
    public decimal? Volume { get; set; }
    public int? Pieces { get; set; }
    public decimal? Weigth { get; set; }
    public bool? DangerousGoods { get; set; }
    public string DgClass { get; set; }
    public string UnNumber { get; set; }
    public Guid? ConsignmentId { get; set; }
    public Guid? ItemId { get; set; }
    public Guid? CommodityId { get; set; }
    public bool? Deleted { get; set; }

My Legging.cs is this:

    public Guid Id { get; set; }
    public DateTime? DateCreated { get; set; }
    public DateTime? DateModified { get; set; }
    public decimal? Cost { get; set; }
    public string LegType { get; set; }
    public string FromLeg { get; set; }
    public string ToLeg { get; set; }
    public Guid? CarrierAccount { get; set; }
    public Guid? ConsignmentId { get; set; }
    public bool? Deleted { get; set; }

I am testing it from postman and it is returning Json Exception. What should be expression then?

Upvotes: 0

Views: 1123

Answers (2)

Swagat Swain
Swagat Swain

Reputation: 505

The issue is with the Lambda Expression. As of now you can not filter an Include statement. If you want a filtered result, you shall have to fetch them all to memory and filter them. In your case, you don't even need to filter the include part. Only including the navigation property will just work fine. Assuming the parameter is used to filter the consignment table.

    // GET: api/Consignments
    [HttpGet("{id}")]
    public async Task<ActionResult<Consignment>> GetConsignment(Guid id)
    {
        var consignment = await _context.Consignment.Where(x=>x.Id == id)
                .Include(conline => conline.ConsignmentLine)
                .FirstOrDefault();
        return consignment;
    }

The above code will simply give you the records from Consignmet Table, and Its ConsignmentLine. Try and let me know if this works.

However, this might throw an JSON.NET Error Self-referencing loop detected for type error. If you are getting this error, then you can resolve the same using the following method.

If you are using AspNet Core, add the followings to the ConfigureServices() method.

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

Happy Coding.<3

Upvotes: 1

LouraQ
LouraQ

Reputation: 6901

As comment said, you can't use any filtering in Include.

And GetConsignment method returns the type of Consignment, not the list set, therefore, you need to convert the consignment variable through FirstOrDefaultAsync or SingleOrDefaultAsync.

Try changing the code to the following :

public async Task<ActionResult<Consignment>>  GetConsignment(Guid id)       
{ 
        var consignment = await _context.Consignment.Where(x=>x.Id == id)
        .Include(conline => conline.ConsignmentLine)
        .FirstOrDefaultAsync();

        return consignment; 
}

And here is my ConsignmentLine.cs :

 public class ConsignmentLine
{
    public int Id { get; set; }
}

To load related data in linq, you can refer to this.

Upvotes: 0

Related Questions