Using Microsoft WebAPI OData version 5.6 (OData v3), if I have the following custom model/DTOs:
public class ParentObject
{
public int ID { get; set; }
public string Title {get; set;}
public ChildObject Child { get; set;}
}
public class ChildObject
{
public string Value { get; set;}
}
And the following controller that projects my database into the model:
public class ParentsController : ODataController
{
public IQueryable<ParentObject> Get()
{
var db = new MyDBContext();
var results = from p in db.parent
select new ParentObject
{
ID = p.id,
Title = p.title,
Child = p.child == null ? null : new ChildObject
{
Value = p.child.value
}
};
return results;
}
}
}
How can I force "Child" to be expanded without the consumer needing to specify $expand=Child in the url?
I want to:
1. Check to see if the consumer already specified the $expand=Child
2. If "Child" is not already included in the expand list, include it.
3. Be sure to respect any other query options
I have looked at several online articles that are either unclear to me or reference an older version of the api that no longer matches up.
I have tried modifying the Action to "Get(ODataQueryOptions opts)" which let's me do something like:
if(opts.SelectExpand == null || !opts.SelectExpand.RawExpand.Contains("Child"))
{
// Add/modify expand clause here.
}
However I am not clear on how to either modify or build up my own ODataQueryOptions object, maintaining all of the other query options and then applying it to the results.
Update 1
I have made some progress. Here's the relevant changes to the controller (the dbcontext query is same as above):
public PageResult<ParentObject> Get(ODataQueryOptions opts)
{
SelectExpandQueryOption expandOpts = null;
if(opts.SelectExpand != null && !opts.SelectExpand.RawExpand.Contains("Child"))
{
expandOpts = new SelectExpandQueryOption(opts.SelectExpand.RawSelect, string.Join(",", new string[] {"Child", opts.SelectExpand.RawExpand }), opts.Context);
}
else if (opts.SelectExpand == null)
{
expandOpts = new SelectExpandQueryOption(null, "Child", opts.Context);
}
// Query from above goes here
if(expandOpts != null)
{
Request.SetSelectExpandClause(expandOpts.SelectExpandClause);
}
var qSettings = new ODataQuerySettings();
qSettings.PageSize = 100;
results = opts.ApplyTo(results, qSettings).AsQueryable() as IQueryable<ParentObject>;
return new PageResult<ParentObject>(results, Request.GetNextPageLink(), Request.GetInlineCount());
}
This seems to work fine when I do not include a "$expand" query option (expandOpts is created). However, when "$expand" is present, I'm getting a ArgumentNullExcpetion on the return statement and can't figure out why.
Request.SetSelectExpandClause
is obsolete so I usedRequest.ODataProperties().SelectExpandClause
property instead – U.P