nick
nick

Reputation: 507

Model Binding in Web API for .NET Core Type Mismatch

I have the following controller which is supposed to create a new object in the database:

[HttpPost]
public ActionResult<Panels> CreateNewPanel(Panels panel)
{

    _context.Panels.Add(panel);
    _context.SaveChanges();

    return CreatedAtAction(nameof(GetPanelById), new { id = panel.ID }, panel);
}

It is receiving some JSON data, example:

 {
        "desc": "test5",
        "frame": 2,
        "aC240v": false
    }

Which maps to the following model:

public class Panels
    {
        public int ID { get; set; }
        public string Desc { get; set; }

        public PanelFrames Frame { get; set; }

        public bool AC240v { get; set; }

    }

It works for the most part if "frame" isn't set, but if it is set to an integer like the code above it fails because it is type PanelFrames not an integer.

PanelFrames is another model that has a one to many relationship with Panels, each Panel can have only one PanelFrame so in the database this is recorded as simply an integer, the PanelFrames ID.

How do I reconcile this so that the integer (which is the PanelFrame ID) get's passed through the API and recorded in the database. The MS documentation doesn't seem to cover this, though it seems like it would be a pretty common occurrence, so I must not be understanding something, or doing something very wrong.

Upvotes: 0

Views: 374

Answers (1)

Ryan
Ryan

Reputation: 20126

If you use EF Core one-to-many relationships and save the principle entity(PanelFrames) id,you just need to add a foreign key for your navigation property in your Panel model.Refer to my below demo:

1.Models

public class Panels
{
    [Key]
    public int ID { get; set; }
    public string Desc { get; set; }

    public int FrameID { get; set; }

    [ForeignKey("FrameID")]
    public PanelFrames Frame { get; set; }

    public bool AC240v { get; set; }

}

public class PanelFrames
{
    [Key]
    public int PanelFramesID { get; set; }
    public string Name { get; set; }

    public List<Panels> Panels { get; set; }
}

2.In my case, I pass json data using postman, so I need to use [FromBody] on action parameters.

json:

 {
    "desc": "test5",
    "frameid": 2,
    "aC240v": false
}

Action:

[HttpPost]
public ActionResult<Panels> CreateNewPanel([FromBody]Panels panel)

Then a new Panel with FrameId would be added into database.

3.If you need to get panels with their Frame, just use Include method in action like

using Microsoft.EntityFrameworkCore;//Add necessary namespaces before
//...
var panels= _context.Panels
    .Include(p => p.Frame)
    .ToList();

Upvotes: 1

Related Questions