【发布时间】:2018-02-27 17:43:02
【问题描述】:
我正在尝试使用 EntityFramework 和 OData v4 构建 API。
问题:我需要一些额外的数据 extraProperty,这些数据不在我的数据库中以创建新的 Item,但 oData 无法识别如果我在POST 调用中向我的 JSON 对象添加一些数据,则作为 Item。
我使用 EntityFrameWork 所以,根据this question,我尝试在我的模型中使用数据注释[NotMapped] 或.Ignore(t => t.extraProperty);。但 oData 似乎忽略了它。
我从这个帖子中得到的所有信息,这个extraProperty,是:
不支持非开放类型的无类型值。
代码
我在 POST 调用中发送的 JSON:
{
"name": "John Doe",
"extraProperty": "Random string"
}
$元数据:
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
<Schema Namespace="MyApi.Models" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityType Name="Items">
<Key>
<PropertyRef Name="id" />
</Key>
<Property Name="id" Type="Edm.Int32" Nullable="false" />
<Property Name="name" Type="Edm.String" Nullable="false" />
</EntityType>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
ODataConfig.cs
namespace MyApi.App_Start
{
public class OdataConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Items>("Items");
config.Count().Filter().OrderBy().Expand().Select().MaxTop(null);
config.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
}
}
}
Items.cs
[Table("Item.Items")]
public partial class Items
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Items(){}
public int id { get; set; }
public string name { get; set; }
[NotMapped] // I already tried this, it's not working
public string extraProperty{ get; set; }
}
MyModel.cs
public partial class MyModel: DbContext
{
public MyModel()
: base("name=MyModel")
{
Database.SetInitializer<MyModel>(null);
}
public virtual DbSet<Items> Items{ get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// I also tried this but not working
modelBuilder.Entity<Items>()
.Ignore(e => e.extraProperty);
}
}
MyController.cs
public class ItemsController : ODataController
{
private MyModeldb = new MyModel();
// POST: odata/Items
public async Task<IHttpActionResult> Post(Items items)
{
// items is always null when enterring here
// and this condition is always triggered
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// Do some stuff with extraProperty here
db.Items.Add(items);
await db.SaveChangesAsync();
return Created(items);
}
}
部分 package.config
<package id="EntityFramework" version="6.2.0" targetFramework="net461" />
<package id="Microsoft.Data.Edm" version="5.8.3" targetFramework="net461" />
<package id="Microsoft.AspNet.OData" version="6.1.0" targetFramework="net45" />
<package id="Microsoft.Data.OData" version="5.8.3" targetFramework="net461" />
<package id="Microsoft.OData.Core" version="7.4.1" targetFramework="net45" />
<package id="Microsoft.OData.Edm" version="7.4.1" targetFramework="net45" />
我也想过做一个拦截器,在调用 post 之前清除我的 json,但是根据this question,Web API OData 不支持查询拦截器...
我该如何处理这个错误并避免它?我真的需要在 POST 方法中处理extraProperty,或者至少在之前处理。
【问题讨论】:
-
异常消息提示您应该使用Open Types 来处理其他数据。
-
您是否只尝试过modelBuilder.Entity
().Ignore(e => e.extraProperty);没有 [NotMapped] 注释? -
另外,您能否在 Fiddler 中捕获 Post 请求并查看是否在 Raw 请求中实际发送了 Items?
-
@hem,raw 很好,我已经尝试过 modelBuilder.Entity
().Ignore(e => e.extraProperty);有和没有 NotMapped。感谢您的评论。 -
@hem,我重试了 modelBuilder.Entity
().Ignore(e => e.extraProperty);没有 NotMapped,它终于奏效了。你能把这个作为答案发布吗,所以我会给你赏金。
标签: c# entity-framework api odata