【问题标题】:APN.NET WebAPI OData controller - post parameters bindingAPN.NET WebAPI OData 控制器 - 发布参数绑定
【发布时间】:2015-06-21 08:29:34
【问题描述】:

当 json 数据包含的属性多于 OData 控制器中定义的 Post 方法所需的属性时,我遇到了向 OData 控制器发送请求的问题。 MVC 控制器应该允许所谓的过度发布,但似乎 OData 控制器不接受它。请查看以下示例。

我有一个简单的实体类:

public class Skill
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [StringLength(100)]
    public string Name { get; set; }

    public SkillAffiliation ApplicableTo { get; set; }
}
  • SkillAffiliation 是一个枚举。

还有一个带有 Post 方法的简单 OData 控制器,如下所示:

public IHttpActionResult Post(Skill skill)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    _dbContext.Skills.Add(skill);
    _dbContext.SaveChanges();

    return Created(skill);
}

问题是我使用了第三方 Web 控件集合,并且应该使用我的 OData 控制器的控件添加了一个额外的 json 属性,基本上 POST 请求如下所示:

{"Name":"TEST2","ApplicableTo":"Vehicle","ApplicableTo_input":"Vehicle"}

所以有一个额外的 ApplicableTo_input 属性——不幸的是,这会导致模型验证错误。 ModelState.IsValid 属性设置为 false,并且出现错误消息“类型 'Mango.Models.Skill' 上不存在属性 'ApplicableTo_input'。确保仅使用类型定义的属性名称。”添加这个额外的属性显然是他们解决方案中的一个错误,将在下一个版本中修复,但是在那之前我必须找到一些解决方法。

我已经尝试将 [Bind(Exclude="ApplicableTo_input")] 属性添加到我的发布操作参数中,但它似乎不起作用。有什么想法吗?

【问题讨论】:

  • 你能提供一个样本来重现它(没有数据库)吗?
  • 技能参数是否为空?
  • 是的,我的 odata 控制器的 Post 方法中的技能参数为 null 并且 ModelState.IsValid == false。
  • 在这里您可以下载说明我的问题的示例:dropbox.com/s/pmqrj4q7101z6ai/Sample_20150417.zip?dl=0

标签: asp.net-web-api odata asp.net-web-api-odata


【解决方案1】:

通过添加字典属性使 SkillWrapper 成为开放实体。

public class SkillWrapper 
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [StringLength(100)]
    public string Name { get; set; }

    public SkillAffiliation ApplicableTo { get; set; }

    public IDictionary<string, object> CustomerProperties { get; set; }
}

使用技能存储价值并保存在数据库中。

public IHttpActionResult Post(SkillWrapper skill)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    var value = new Skill();
    ...//get property value form skill
    _dbContext.Skills.Add(value);
    _dbContext.SaveChanges();

    return Created(value);
}

【讨论】:

  • 我已经尝试过这种方法,但不是创建一个开放实体,而是为我的 odata 服务的 edm 模型添加了一个新的集合属性:
  • 我认为您在 DB 中的技能没有 CustomProperties 列,所以建议使用包装器,而不是直接更改技能,所以现在可以使用了吗?
  • 我同意最好添加一个包装器,但这只是一个演示问题的示例。正如我在之前的评论中提到的,不幸的是,这并没有帮助 - 当我转到 odata/$metadata 时,Skill 实体未标记为开放实体,而是将一个名为 CustomProperties 的新属性添加到实体中。我不知道为什么会这样,我发现了许多其他提示,添加 IDictionary 属性应该使它成为一个开放实体,但不知何故它不适用于此示例。
  • 您使用的是 OData WebApi V4 还是 V3? V3不支持开放实体,更多关于V4开放实体类型的细节可以参考asp.net/web-api/overview/odata-support-in-aspnet-web-api/…odata.github.io/WebApi/#02-03-model-builder-nonconvention
猜你喜欢
  • 1970-01-01
  • 2015-10-29
  • 2018-12-24
  • 2016-05-11
  • 2013-04-20
  • 1970-01-01
  • 2014-09-29
  • 2016-11-07
  • 1970-01-01
相关资源
最近更新 更多