Reputation: 12814
I'm building a proof-of-concept API using ASP.NET Core 2.1, Web.API, and OData (7.0.0-beta4).
One of my OData endpoints is responsible for basic CRUD operations on an Employer
entity. The POST
endpoint - which creates a brand new Employer
record - is defined like this:
// POST: api/Employers
[HttpPost]
public async Task<IActionResult> PostEmployer([FromBody] Employer employer)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
_context.Employers.Add(employer);
await _context.SaveChangesAsync();
return CreatedAtAction("GetEmployer", new { id = employer.Id }, employer);
}
My Employer
entity is defined like this:
namespace MyProject.Models
{
public class Employer
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
}
}
If I hit this OData endpoint with a POST
body like this:
{
"Name": "My Employer",
"IsActive": true
}
I get an error message:
InvalidOperationException: No route matches the supplied values.
This is because the Id
property is required, but is not provided in my JSON. However, I don't want to provide the Id
property, because this property will be auto-generated by the database. If I do provide the Id
property, my request is successfully routed, but I get an Entity Framework error later in the process (Cannot insert explicit value for identity column
), which makes sense.
How can I make my OData endpoint ignore the required Id
property during a POST
request?
Upvotes: 1
Views: 1046
Reputation: 12814
Figured it out - it turns out the issue had nothing to do with the Id
property in my entity class. Instead, the problem was this line:
return CreatedAtAction("GetEmployer", new { id = employer.Id }, employer);
The framework must do some kind of validation on the specified action ("GetEmployer"), and it was throwing an error that this action is invalid.
I'm not sure how to correct this string value, but I can avoid the issue altogether by using a simpler return value:
return Ok(new { Id = employer.Id });
Upvotes: 1
Reputation: 396
Try adding the [DataContract] and [DataMember] attributes to your Employer model:
[DataContract]
public class Employer
{
[DataMember(Name = "Id", IsRequired=false, EmitDefaultValue=false)]
public int Id { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
}
More info on DataMemberAttribute properties: https://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute_properties(v=vs.110).aspx
Upvotes: 1