2
votes

I'm trying to make OData return the number of entities from the database when I pass it $inlinecount=allpages in the uri. I have read in Stack Overflow that I should return IQueryable instead of IHttpActionResult, however that didn't solve the problem. I also tried to follow the tutorials on the asp.net website, but that also didn't give any results.

[EnableQuery(
        PageSize = BuildingConstants.BuildingsPerPage,
        MaxTop = BuildingConstants.MaxBuildingsPerPage,
        AllowedArithmeticOperators = AllowedArithmeticOperators.None,
        AllowedLogicalOperators = AllowedLogicalOperators.None,
        AllowedFunctions = AllowedFunctions.SubstringOf,
        AllowedQueryOptions = AllowedQueryOptions.Filter | AllowedQueryOptions.OrderBy | AllowedQueryOptions.Top | AllowedQueryOptions.Skip | AllowedQueryOptions.InlineCount)]
    [ResponseType(typeof(IEnumerable<ListedBuildingResponseModel>))]
    public IQueryable<ListedBuildingResponseModel> Get()
    {
        var buildings = this.buildings
            .GetBuildings()
            .ProjectTo<ListedBuildingResponseModel>();

        return buildings;
    }

This is everything I have written regarding OData. The controller inherits ApiController, not ODataController. In the Register method I haven't added any OData routes or model builders. $top, $skip, $orderby and everything else is working just fine, but $inlinecount=allpages. Any suggestions on how to solve the problem?

1
Isn't ODataV4 $count=true instead of $inlinecount? - Marvin Smit
"Message": "The query parameter '$count' is not supported." - Hristo Stoichev
Add it to the allow list? "AllowedQueryOptions.Count". - Marvin Smit
@MarvinSmit There is no such query option "count". Even if I delete all the parameters from the attribute and leave it empty like [EnableQuery] I get the same error message. - Hristo Stoichev
I found out that I have installed the old NuGet package, so I deleted the old one and installed the OData v4 package. Now, I can use count=true, but I still don't get the entities count in the response. I tried to return both IHttpActionResult and IQueryable<>, but without any success. - Hristo Stoichev

1 Answers

0
votes

I managed to make count=true work by adding the following code:

 public static void Register(HttpConfiguration config)
    {
        config.MapODataServiceRoute("odata", "odata", model: GetEdmModel());
    }

    private static IEdmModel GetEdmModel()
    {
        var builder = new ODataConventionModelBuilder();
        builder.EntitySet<ListedBuildingResponseModel>("Buildings");

        builder.EnableLowerCamelCase();
        var edmModel = builder.GetEdmModel();
        return edmModel;
    }

Now everything is working fine except I can't use my other actions in the class, because I get 406 error status code and I don't know why. I don't want my other actions to support OData, so I am thinking for possible solutions. Doing a separate controller only for the OData action is an option, but I have also households, expenses and debts controllers whose Get methods I want to support OData. This means, I need to create 4 more controllers with only 1 Get method. Is there a way I can create a single SearchController with methods GetBuildings, GetHouseholds, GetExpenses, and GetDebts that return different types? Because, as far as I understand this line of code

uilder.EntitySet<ListedBuildingResponseModel>("Buildings");

somehow "binds" the BuildingsController to ListedBuildingResponseModel.