无绑定函数发送和接收原始集合

本文关键字:原始 集合 绑定 函数 | 更新日期: 2023-09-27 18:17:14

需要一个关于如何将基本类型集合传递给未绑定的函数/操作以及如何返回基本类型集合的示例
例如整数的列表或数组。
下面是一个简单的例子。

List<int> GetEvenNumbers(List<int> numbers)
{
// loop through numbers collection and return a list of the even numbers
}

下面的站点讨论了使用函数/动作,但没有解释传递/接收集合。

http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/odata-actions-and-functions

https://aspnet.codeplex.com/sourcecontrol/latest样品/WebApi OData v4/

我甚至在"教我如何使用代码"上发布了一个建议,但没有收到回应。
http://aspnet.uservoice.com/forums/228522-show-me-how-with-code/suggestions/6264729-odata-v4-passing-collection-as-parameter-to-unbou

这里是一些代码,我有,但它似乎不工作。

// in the controller
[HttpGet]
[ODataRoute("GetEvenNumbers(numbers={numbers})")]
public IHttpActionResult GetEvenNumbers(List<int> numbers)
{
    List<int> evenNumbers = new List<int>();
    foreach (var number in numbers)
    {
        if (number % 2 == 0)
        {
            evenNumbers.Add(number);
        }
    }
    return Ok(evenNumbers);
}
// in the WebApiConfig
var testCollectionFunction = builder.Function("GetEvenNumbers");
testCollectionFunction.CollectionParameter<int>("numbers");
testCollectionFunction.ReturnsCollection<int>();

在WCF中,这是非常简单的,但在OData中,它不是那么简单。

无绑定函数发送和接收原始集合

据我所知,webapi odata不允许在函数参数中集合。但是你可以使用Actions作为一种变通方法。

模型构建器:

        var testCollectionFunction = modelBuilder.Action("GetEvenNumbers");
        testCollectionFunction.CollectionParameter<int>("numbers");
        testCollectionFunction.ReturnsCollection<int>();

控制器:

    [HttpPost]
    [ODataRoute("GetEvenNumbers")]
    public IHttpActionResult GetEvenNumbers(ODataActionParameters parameter)
    {
        IEnumerable<int> numbers = parameter["numbers"] as IEnumerable<int>;
        List<int> evenNumbers = new List<int>();
        foreach (var number in numbers)
        {
            if (number % 2 == 0)
            {
                evenNumbers.Add(number);
            }
        }
        return Ok(evenNumbers);
    }
请求:

POST http://localhost:44221/odata/GetEvenNumbers HTTP/1.1
Host: localhost:44221
Connection: keep-alive
Content-Length: 17
{"numbers":[1,2]}

反应:

HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=full
OData-Version: 4.0
Content-Length: 109
{
  "@odata.context":"http://localhost:44221/odata/$metadata#Collection(Edm.Int32)","value":[
    2
  ]
}

所以我想提供和更新这篇文章。我正在使用Web API 2.2玩OData v4。我可以将参数传递给未绑定的函数。

下面是我的Register方法中的构建器代码。

ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Employee>("Employees");
//other stuff here
builder.Function("EmployeesWithParameters")
       .ReturnsCollectionFromEntitySet<Employee>("Employees")
       .CollectionParameter<string>("Ids");

这是我的控制器上的实际方法调用。

    [HttpGet]
    [ODataRoute("EmployeesWithParameters(Ids={Ids})")]
    public IQueryable<Employee> EmployeesWithParameters([FromODataUri]string[] Ids)
    {
        IQueryable<Employee> result = db.Employees.Where(p => Ids.Contains(p.EmployeeId) );
        return result; ;
    }

正如Cyrus的回答所说,OData函数既可以返回集合,也可以将集合作为参数。

在我的例子中,我有一个名为"MostPopular"的函数,定义为:

        var mostPopFunc = svcHist.Collection.Function("MostPopular");
        mostPopFunc.Parameter<DateTime>("From");
        mostPopFunc.CollectionParameter<ServiceCodes>("ServiceCodes");
        mostPopFunc.CollectionParameter<int>("ServiceUnits");
        mostPopFunc.Parameter<string>("SearchCCL");
        mostPopFunc.Parameter<int>("ListLength").OptionalParameter = true;
        mostPopFunc.ReturnsCollection<ciExternalPartnerPopularResult.MarcIdPopularity>();

由于此函数绑定到实体集,因此不需要提供路由映射,并且函数声明简化为:

[HttpGet]
public async Task<IHttpActionResult> MostPopular([FromODataUri] DateTimeOffset from, [FromODataUri] IEnumerable<ServiceCodes> serviceCodes, 
                                                 [FromODataUri] IEnumerable<int> serviceUnits,
                                                 [FromODataUri] string searchCcl, [FromODataUri] int listLength = ListLengthDefault)
{ // ...
}

int和其他简单类型不需要[FromODataUri]装饰,但我不太介意它们。考虑到参数的数量,这个函数有点重,但是我已经没有时间为这个函数找出一个更好的接口了。

最后,要从PostMan(或浏览器)调用它,GET请求看起来像这样:
{{url}}/ServiceHistories/Default.MostPopular(From=2016-10-07T12:41:59Z,ServiceCodes=['OnLoan'],ServiceUnits=[6471,6473],SearchCCL='TI+SE=Harry',ListLength=10)

这迫使我修改我的网页。

<system.web>
  <!-- This web service accepts datetimeoffset as a parameter and requires the ":" character to be supplied as part of the URL -->
  <httpRuntime targetFramework="4.5" requestPathInvalidCharacters="&lt;,&gt;,%,&amp;,',?" />
</system.web>