Can metadata be added to ODataValue to support using count?
When using the following attribute parameters
[ProducesResponseType( typeof( ODataValue<IEnumerable<Color>> ), Status200OK )]
It currently produces this as the model:
{
"value": []
}
Instead of what is really returned:
{
"@odata.context":"http://localhost/$metadata#Collection(NS.Color)",
"@odata.count": 3,
"@odata.nextLink":"http://localhost/Customers(5)/Colors?$count=true&$skip=2",
"value": []
}
I have tried creating a class for it myself, however, the swagger docs produced then don't have most of the odata parameters like $filter, $orderby etc.
When you say that you _"tried creating a class for it myself..."_, do you mean that you extended ODataValue\
These particular attributes are called _annotations_; specifically _instance annotations_. The @odata prefix is reserved for annotations produced by OData itself; however, it is possible to have your own annotations.
Your request isn't without merit, but there are some interesting challenges to supporting it. These particular annotations are driven by the media type parameter odata.metadata, which can have a value of full, minimal, or none. When the value is none, no annotations are present and the response looks like vanilla JSON. For example, if the media type is application/json; odata.metadata=none.
To complicate things further, the possible annotations can depend on supported query options. For example, if $count is not allowed, then you'll never get the @odata.count annotation is responses.
It's worth taking a look at this more in-depth, but I wanted to provide some context with regard to the complexities involved. Subclassing ODataValue\
Thanks.
I provided my own stand-in class, I'll extend ODataValue
I had a feeling it wouldn't be simple with the number of OData options!
Thanks for responding so quick 馃槂
I extended ODataValue but got the same output, with only $select and $expand listed a parameters.
I've had a look through the code and found that it is treating it as a "single result" because is sees that the generic type definition is not ODataValue<T>.
The check could be changed to look at the base type as well if it doesn't match, that way extending ODataValue<T> will work, what do you think @commonsensesoftware ?
Extending ODataValue also affects the response model, it ignores changes to the entity type configuration so something like order.Ignore(o => o.Description); does nothing and the Description property is still listed in the model shown in the swagger doc.
You're not by chance trying to actually return ODataValue\[ProducesResponseType] attribute, you can provide a surrogate type that is in the correct shape of the output. If you use ODataValue\
Ultimately, to get the correct output, the API Explorer _unwraps_ T in ODataValue\
If you can share what your extended type looks like and how you've applied it to an action, I can see if I can't reproduce the behavior and/or come up with some other recommendations.
No, I'm returning IQueryable<T>. Here's what I have:
[ODataRoute]
[ProducesResponseType(typeof(ODataValueWithCount<IEnumerable<CustomerOutputModel>>), Status200OK)]
[EnableQuery(AllowedQueryOptions = Select | Skip | Top | Count | OrderBy | Filter,
AllowedOrderByProperties = "accountNumber,company")]
public IQueryable<CustomerOutputModel> Get()
{
var customers = _customerService.GetCustomers();
return customers;
}
public class ODataValueWithCount<T> : ODataValue<T>
{
[JsonProperty("@odata.context")]
public string ODataContext { get; set; }
[JsonProperty("@odata.count")]
public int ODataCount { get; set; }
[JsonProperty("@odata.nextLink")]
public string ODataNextLink { get; set; }
}
public void Apply(ODataModelBuilder builder, ApiVersion apiVersion)
{
var account = builder.EntitySet<CustomerOutputModel>("Customers").EntityType;
account.Ignore(p => p.AccountIndex);
account.HasKey(k => new { k.AccountNumber });
}
And this is how swagger looks:


@commonsensesoftware Have you got everything you need on this or can I help further?
Everything you have is correct. The issue that the IsODataValue extension method isn't correct. As written, it will only allow types of ODataValue\