【问题标题】:POST-ing a new entity to a Web.API OData endpoint without an ID将新实体发布到没有 ID 的 Web.API OData 端点
【发布时间】:2018-11-15 01:54:32
【问题描述】:

我正在使用 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),这是有道理的。

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

【问题讨论】:

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


    【解决方案1】:

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

    [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

    【讨论】:

    • 感谢您的回复!我试了一下,现在路由按预期工作 - 但不幸的是,我的 ModelState 被标记为无效,并显示错误消息 Does not support untyped value in non-open type.。因此,employer 变量为 null
    • Id 属性必须是可为空的整数:public int? Id
    • 我已经尝试了两种方法 - (使用 Id 属性可空和不可空),但没有运气 - 我收到相同的错误消息。
    • 该错误似乎是由于 JSON 中有一个属性被 POST 到模型中不存在的服务器(stackoverflow.com/questions/45948893/…)。你能仔细检查你的 JSON 输入是否有额外的属性吗?我假设您发布了一个简化的 Employer 类/JSON,因为我没有看到发布的 JSON 示例有任何问题。不知道还有什么可能。
    • 感谢您的帮助 - 结果与实体类无关(请参阅我的回答)。
    【解决方案2】:

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

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

    框架必须对指定的操作(“GetEmployer”)进行某种验证,并抛出此操作无效的错误。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-04
      • 2019-11-04
      • 1970-01-01
      • 2018-12-28
      • 2013-12-06
      • 1970-01-01
      • 2013-09-02
      • 1970-01-01
      相关资源
      最近更新 更多