Reputation: 45
Hoping someone can hepl with an issue I've been having. I've created a Web API that fetches records from the a database. I have the following functions in place which work ok:
localhost:8080/api/Budgets -- Returns all Budgets
localhost:8080/api/Budgets(799) -- Returns all for contract 799
What I'm looking for is to be able to pass in two parameters to allow me to do calulations on the records retrieved so something like:
localhost:8080/api/Budgets(799)/215 -- Where 799 is the contract Number and 215 is a material number.
This will allow me to return a dataset of only materials for that budget that I can then do calculations on. There is only one SQL table for this which contains both the contract number and material number as well as a load of other figures.
Here's what I have so far but it doesnt seem to be working:
public IHttpActionResult Get()
{
return Ok(context.Budgets);
}
public IHttpActionResult Get([FromODataUri] int key)
{
var budgets = context.Budgets.FirstOrDefault(p => p.ProjectNo == key);
if (budgets == null)
{
return NotFound();
}
return Ok(budgets);
}
[ODataRoute("GetMaterialUsage(ProjectId={ProjectId},ResourceCode={ResourceCode})")]
public IHttpActionResult GetMaterialUsage([FromODataUri] int ProjectId, [FromODataUri] string ResourceCode)
{
var budgets = context.Budgets.FirstOrDefault(p => p.ProjectNo == ProjectId && p.ResourceCode == ResourceCode);
if (budgets == null)
{
return NotFound();
}
return Ok(budgets);
}
WebApiConfig:
ODataModelBuilder builder = new ODataConventionModelBuilder();
// Web API configuration and services
builder.EntitySet<BudgetTypes>("BudgetTypes");
builder.EntitySet<Budgets>("Budgets");
var function = builder.Function("GetMaterialUsage");
function.Parameter<int>("ProjectId");
function.Parameter<string>("ResourceCode");
function.ReturnsCollectionFromEntitySet<Budgets>("Budgets");
// Web API routes
config.MapHttpAttributeRoutes();
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "api",
model: builder.GetEdmModel()
);
Can anyone shine some light on how this can be done? I just want to pass 2 parameters to a function from the url.
At the moment the following links return 404: localhost:8080/api/Budgets(752,230) localhost:8080/api/Budgets(ProjectNo=752,ResourceCode=230)
Upvotes: 0
Views: 3743
Reputation: 2142
you have specify the ODataRoute:
[ODataRoute("GetMaterialUsage(ProjectId={ProjectId},ResourceCode={ResourceCode})")]
And second parameter is string, so you should call like
localhost:8080/api/GetMaterialUsage(ProjectNo=752,ResourceCode='230')
If you need something like your not-working url, you need bound this function to your entity Budget, you will know how to do it refer to this page: http://odata.github.io/WebApi/#04-06-function-parameter-support
Upvotes: 1
Reputation: 55
I'm not 100% sure on this answer, because I've used OData a little differently, but I think the principle is still the same; I believe the key is to add a 2nd nullable parameter to your 2nd Get function...
//try: localhost:8080/api/Budgets(799,251)
//use this in-place of your second get function
//note the nullable (optional) 2nd parameter
public IHttpActionResult Get([FromODataUri] int key, [FromODataUri] int? key2 = null)
{
if (key2 == null)
{
//carry-on as usual using the 1-param code
var budgets = context.Budgets.FirstOrDefault(p => p.ProjectNo == key);
if (budgets == null)
{
return NotFound();
}
return Ok(budgets);
}
else
{
//if a second param is also supplied...
}
}
Upvotes: 0