Web API和OData - 传递多个参数

20

能否让OData做到以下事情?我想通过传递可能不是主键的参数来查询REST调用。 我是否可以像这样调用REST方法 -> GetReports(22, 2014) 或者 Reports(22, 2014)

[HttpGet]
[ODataRoute("Reports(Id={Id}, Year={Year})")]
public IHttpActionResult GetReports([FromODataUri]int Id, [FromODataUri]int Year)
{
    return Ok(_reportsRepository.GetReports(Id, Year));
}

这是我的最新更改。

//Unbound Action  OData v3
var action = builder.Action("ListReports");
action.Parameter<int>("key");
action.Parameter<int>("year");
action.ReturnsCollectionFromEntitySet<Report>("Reports");

我的方法控制器ReportsController:

[HttpPost]
[EnableQuery]
public IHttpActionResult ListReports([FromODataUri] int key, ODataActionParameters parameters)
{
    if (!ModelState.IsValid)
    {
        throw new HttpResponseException(HttpStatusCode.BadRequest);
    }

    int year = (int)parameters["year"];
    
    return Ok(_reportsRepository.GetReports(key, year).Single());
}

我尝试通过以下方式调用URL:

http://localhost:6064/odata/Reports(key=5,year=2014)/ListReports

未找到与请求URI 'http://localhost:6064/odata/Reports(key%3D5%2Cyear%3D2014)/ListReports' 匹配的HTTP资源。

2个回答

34

您可以定义一个名为GetReports的函数导入,该导入具有两个参数。

(注意:函数导入的名称不能与实体集名称相同)

将EDM模型配置为:

var builder = new ODataConventionModelBuilder();
builder.EntitySet<Report>("Reports");
var function = builder.Function("GetReports");
function.Parameter<int>("Id");
function.Parameter<int>("Year");
function.ReturnsCollectionFromEntitySet<Report>("Reports");
var model = builder.GetEdmModel();

然后按如下方式编写您的方法:

[HttpGet]
[ODataRoute("GetReports(Id={Id},Year={Year})")]
public IHttpActionResult WhateverName([FromODataUri]int Id, [FromODataUri]int Year)
{
    return Ok(_reportsRepository.GetReports(Id, Year));
}

然后请求

Get ~/GetReports(Id=22,Year=2014)

会起作用。


这可以用Odatav3怎么做?v3没有相应的函数。 - Nate
我必须使用Odata v3,因为我正在使用Jaydata,而且它似乎只能与v3一起使用。如果我使用Jaydata和Odata v4,则会引发404错误。有没有关于v3的解决方案?谢谢。 - Nate
1
在v3中,您可以定义一个操作。如果您定义了一个未绑定的操作,则必须使用HttpPost并通过请求正文传递参数,并且您需要在控制器中添加一个方法“HandleUnmappedRequest”以匹配未绑定的操作请求。如果将其定义为绑定到实体集的绑定操作,尽管这没有意义,但可以添加一个方法“[ActionName]OnCollectioinOf[EntityTypeName]”,并调用HttpPost“〜/[EntitySetName]/[ActionName]”,并在请求正文中传递参数。 - Feng Zhao
在 https://aspnet.codeplex.com/SourceControl/latest#Samples/ReadMe.txt 上有许多示例。要查看 v3 操作示例,请访问 https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v3/ODataActionsSample/ODataActionsSample/ReadMe.txt。 - Feng Zhao
能否在get方法上实现参数?方法名称只需为“get”,并使用ODataRoute。 - gee'K'iran
显示剩余5条评论

3
对于OData v4.0端点,您不必将其作为函数处理,只需简单地执行以下操作...
public class ReportsController : ODataController
{
    [EnableQuery]
    [ODataRoute("Reports({id}, {year})")]
    public IQueryable<ReportModel> Get([FromODataUri] int id, [FromODataUri] int year)
    {
        ...
    }
}

然后你可以像这样调用它...
/Reports(42, 2019)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接