Xorcist
Xorcist

Reputation: 3311

Web API 2.2 - OData v4 (Manually Parsing Uri + Expanding)

I have an ODataController with a Get method as such:

public IHttpActionResult Get(ODataQueryOptions<MyModel> queryOptions) {
  IQueryable<MyModel> models = _Models.AsQueryable(); // _Models Defined in Controller as List<MyModel> and is already populated with nested data for both .LevelOne and .LevelOne.LevelTwo which are two other Lists.

  Uri fullrequest = Request.GetRequestContext().Url.Request.RequestUri; // http://localhost:8080/odata/Root?$expand=LevelOne($expand=LevelTwo)
  Uri serviceroot = new Uri(controller.GetLeftPart(UriPartial.Path).Replace("/Root", "")); // http://localhost:8080/odata
  String metadata = service + "/$metadata"; // http://localhost:8080/odata/$metadata

  IEdmModel model = EdmxReader.Parse(XmlTextReader.Create(metadata));
  ODataUriParser parser = new ODataUriParser(model, serviceroot, fullrequest);
  SelectExpandClause selectAndExpand = parser.ParseSelectAndExpand();

//Only one of the two below lines is ever commented in...
  Request.ODataProperties().SelectExpandClause = queryOptions.SelectExpand.SelectExpandClause; // This line will work
  Request.ODataProperties().SelectExpandClause = selectAndExpand; // This line will not work

  return Ok(models);
}

using my manually parsed selectAndExpand does not expand the dataset, but using the predefined queryOptions one does. Any ideas why? Both objects appear to contain the same information while viewed in the debugger, but I must be missing something. I want to be able to parse the URI myself, without the need for the ODataQueryOptions at all.

Upvotes: 0

Views: 2041

Answers (1)

Xorcist
Xorcist

Reputation: 3311

What I ended up doing, was building a new ODataQueryOptions object based off the original request, and then pulling just the SelectExpandClause from that. It doesn't answer my initial question, but it is a somewhat working solution for not having to pass in a ODataQueryOptions parameter. See my Code below:

public IHttpActionResult Get() {
//Get Queryable Item (in this case just a list made queryable)
  IQueryable<MyModel> models = _Models.AsQueryable();

//Create new ODataQueryContext based off initial request (required to create ODataQueryOptions)
  ODataQueryContext selectAndExpandContext = new ODataQueryContext(Request.ODataProperties().Model, typeof(MyModel), Request.ODataProperties().Path);

//Create new ODataQueryOptions based off new context and original request
  ODataQueryOptions<Employee> selectAndExpandOptions = new ODataQueryOptions<Employee>(selectAndExpandContext, Request);

//Attach Select + Expand options to be processed
  if (selectAndExpandOptions.SelectExpand != null) {
    Request.ODataProperties().SelectExpandClause = selectAndExpandOptions.SelectExpand.SelectExpandClause;
  }

  return Ok(models);
}

Upvotes: 2

Related Questions