I made a partial class file to add new properties to my Entity-Framework generated model.
I am using WebAPI + OData, and the $metadata doesn't list my new/custom properties, and so the JSON it returns doesn't include my new/custom properties.
For example, let's say my Entity is "Person"
"Person" has one Database property; NumSpouses; an int which is returned in $metadata like this:
<Property Name="NumSpouses" Type="Edm.Int32"/>
That's great, but I added a property like this to a separate file, with a partial class:
public partial class Person {
...
public string MarriedStatus {
get { return this.NumSpouses==0 ? "Single" : "Married"; }
}
...
}
How can I get this Property available in my OData responses?
<Property Name="MarriedStatus" Type="Edm.String"/>
Currently, if I asked for MarriedStatus
in $expand
(as if it were a NavigationProperty.... which it's not [I thought I'd try $expand anyway as if it magically provided custom properties]), I'd get a message like this:
{
"odata.error":{
"code":"","message":{
"lang":"en-US","value":"The query specified in the URI is not valid. Could not find a property named 'MarriedStatus' on type 'fakeDataModels.Person'."
},"innererror":{
"message":"Could not find a property named 'MarriedStatus' on type 'fakeDataModels.Person'.","type":"Microsoft.Data.OData.ODataException","stacktrace":" at ..."
}
}
}
MarriedStatus
is a calculated/readonly property. The ASP.NET implementation of OData does not currently support such properties. As a workaround, add a setter that throws NotImplementedException
.
public string MarriedStatus {
get { return this.NumSpouses > 0 ? "Married" : "Single"; }
set { throw new NotImplementedException(); }
}
Optionally, if you are using OData V4, you can annotate MarriedStatus
to specify that it is calculated. See Yi Ding's answer to OData read-only property. But the annotation is advisory only; it does not prevent clients from attempting to set a calculated property (e.g., in a POST
request).
In addition to the answer of lencharest. You should use the Ignore() function of the Entity Framework fluent API instead of the [NotMapped] attribute. Because OData looks for this attribute to ignore properties for serialization. If you use the fluent API you will not have this problem.
dbModelBuilder.Entity<TEntity>()
.Ignore(i => i.ComputedProperty);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With