AspNetCoreOData
AspNetCoreOData copied to clipboard
Using JsonDocument property for models
Hi there,
I'm trying to leverage JsonDocument as part of dto classes and add ability to filter on such properties. I'm facing two issues here:
- As I'm not using neither OdataController nor OData routing I don't need to provide EdmModel and thus I have no way to tell that my JsonDocument is an Open type which supports property access
- I have no way to intercept Expression building procedure in FilterBinder so I could convert dynamic property access to calls to JsonDocuments GetProperty().GetRawText() https://github.com/OData/AspNetCoreOData/blob/dad7c4cf04202a26e61b4e1517443ae9e81eb646/src/Microsoft.AspNetCore.OData/Query/Expressions/QueryBinder.cs#L299 Because obviously JsonDocument have no PropertyInfo (I even tried to wrap JsonDocument into DynamicObject)
Could someone suggest a proper way of doing this?
@forik
Would you please share me with your metadata? and want to know why do you want to use JsonDocument as the container?
In OData WebApi, IDictionary<string, object> is used by default as the container for the dynamic properties.
@xuzhg I don't create a edml model thus don't have a metadata. I'm using just OdataQueryOptions<T> and it's ApplyTo(Queryable) method to do filtering. regarding to JsonDocument - it is a part of a database table which gets mapped to postgresql's jsonb column and I want to be able to filter over this column using OData. I already figured out that I need to provide my own FilterBinder to rewrite Expression for JsonDocument type, but the problem is FilterBinder fails to create an Expression which involves JsonDocument container
I found a workaround with this https://github.com/OData/AspNetCoreOData/issues/575
- Add filter to controllers to update RequestContainer in ODataQueryOptions Context
- Register custom filter binder as singleton into the global service provider 2.1 Register some other dependencies required in RequestContainer (ODataQuerySettings, OrderByQueryValidator, ODataUriResolver, ODataSimplifiedOptions, ODataUriParserSettings). All as singleton
- Make some kind of fake property that I don't send to the client, but that has the required structure. In my case it is a list of elements with string name and value
- CustomFilterBinder must proxy filter request from fake field to JsonDocument field
It works with requests like myCollection/any(keyValue:keyValue/key eq 'someKey' and keyValue/value eq 'someValue')
@osadchii
Thanks for the steps. would you be able to share some sample code for step 4 (CustomFilterBinder must proxy filter request from fake field to JsonDocument field)? I am running into the same issue at the moment.
@osadchii I'm also interested in a code snippet for step 4.
I've basically the same problem using a JsonDocument in a model because of the combination entity framework and postgres.