将新实体发布到没有ID的Web.API OData端点

时间:2018-06-05 14:19:21

标签: c# asp.net asp.net-web-api asp.net-core odata

我正在使用ASP.NET Core 2.1,Web.API和OData(7.0.0-beta4)构建概念验证API。

我的一个OData端点负责Employer实体的基本CRUD操作。 POST端点 - 创建全新的Employer记录 - 定义如下:

// 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);
}

我的Employer实体的定义如下:

namespace MyProject.Models
{
    public class Employer
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public bool IsActive { get; set; }
    }
}

如果我用这样的POST身体点击这个OData端点:

{
    "Name": "My Employer",
    "IsActive": true
}

我收到错误消息:

InvalidOperationException: No route matches the supplied values.

这是因为Id属性是必需的,但我的JSON中没有提供。但是,我不想提供Id属性,因为此属性将由数据库自动生成。如果我提供Id属性,我的请求已成功路由,但我在稍后的过程中遇到了实体框架错误(Cannot insert explicit value for identity column),这是有道理的。

如何在Id请求期间让我的OData端点忽略所需的POST属性?

2 个答案:

答案 0 :(得分:1)

尝试将[DataContract]和[DataMember]属性添加到您的雇主模型中:

[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; }
}

有关DataMemberAttribute属性的更多信息:https://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute_properties(v=vs.110).aspx

答案 1 :(得分:1)

想出来 - 事​​实证明这个问题与我的实体类中的Id属性无关。相反,问题是这一行:

return CreatedAtAction("GetEmployer", new { id = employer.Id }, employer);

框架必须对指定的操作进行某种验证(&#34; GetEmployer&#34;),并且抛出了此操作无效的错误。

我不确定如何更正此字符串值,但我可以通过使用更简单的返回值来完全避免此问题:

return Ok(new { Id = employer.Id });