MapODataRoute and ODataQueryOptions

蓝咒 提交于 2020-01-02 15:38:50

问题


Im building a WebAPI OData solution that handles untyped entity objects, as described in this excellent post. Like that post, I define my EdmModel upfront, and use the MapODataRoute method and pass in the model to use:

config.Routes.MapODataRoute("odata", "odata", ModelBuilder.GetEdmModel());

However, this does not seem to work with ODataQueryOptions parameter in my methods:

Get(ODataQueryOptions query)
{
}

It gives the following error: The given model does not contain the type 'System.Web.Http.OData.IEdmEntityObject'. Parameter name: elementClrType

Is there any way to get ODataQueryOptions to work with MapODataRoute?


回答1:


You should build the ODataQueryOptions manually in your controller action in untyped mode. Sample code follows,

ODataPath path = Request.GetODataPath();
IEdmType edmType = path.EdmType;

IEdmType elementType = edmType.TypeKind == EdmTypeKind.Collection 
    ? (edmType as IEdmCollectionType).ElementType.Definition 
    : edmType;

// build the typeless query options using the element type.
ODataQueryContext queryContext = new ODataQueryContext(Request.GetEdmModel(), elementType);
ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, Request);



回答2:


Ive managed to do it as follows:

ODataPath path = Request.GetODataPath();
IEdmType edmType = path.EdmType;   

private ODataQueryOptions GetODataQueryOptions(IEdmType edmType)
    {
        IEdmModel model = Models.ModelBuilder.GetEdmModel();
        ODataQueryContext queryContext = new ODataQueryContext(model, edmType);
        ODataQueryOptions queryOptions = new ODataQueryOptions(queryContext, this.Request);

        return queryOptions;
    }

This works for most query options, but crashes with $select and $expand: The type 'Collection([Org.Microsoft.Product Nullable=False])' is not an entity type. Only entity types support $select and $expand. Is there a way to avoid this exception gracefully when a client tries to filter with $select and $expand, or should i just write something like

if (Request.RequestUri.Query.Contains("select")) { return errormessage }

Also, and more importantly, how would one apply these query options to an EdmEntityObjectCollection which gets returned in the first method?

queryOptions.ApplyTo(collectionProduct.AsQueryable()); // wont work...

(perhaps it is better practice to dynamically build your collection in regards to the query options anyway)



来源:https://stackoverflow.com/questions/19951261/mapodataroute-and-odataqueryoptions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!