I'm trying to build an API with EntityFramework and OData v4.
Issue : I need some extra data, extraProperty
, that are not in my DB to create a new Item
, but oData won't recognize this as an Item
if I add some data to my JSON object in my POST
call.
I use EntityFrameWork so, according to this question I tried to use the data annotation [NotMapped]
or .Ignore(t => t.extraProperty);
in my model. But oData seems to ignore it.
All I get from this POST, with this extraProperty
, is :
Does not support untyped value in non-open type.
Code
JSON I send in my POST call :
{
"name": "John Doe",
"extraProperty": "Random string"
}
$metadata :
<?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);
}
}
Partial 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" />
I also thought to make an interceptor, to purge my json before post is called, but according to this question, Web API OData does not support query interceptor...
How can I deal with this error and avoid it ? I really need to process extraProperty
in POST method, or at least, just before.