根据这里的文件......
http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v3/odata-actions
...
将操作绑定到实体集
在上一个示例中,操作绑定到单个实体:客户端对单个产品进行评级.您还可以将操作绑定到实体集合.只需进行以下更改:
在EDM中,将操作添加到实体的Collection属性.
var rateAllProducts = builder.Entity().Collection.Action("RateAllProducts"); 在控制器方法中,省略关键参数.
[HttpPost] public int RateAllProducts(ODataActionParameters parameters){// ....}
为什么当我这样做时它不起作用......
发票参考:
public class InvoiceReference
{
public string InvoiceNumber { get; set; }
public int SupplierId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
行动设定:
var getByRefs = Builder.EntityType<SIHead>().Collection.Action("ByRefs");
getByRefs.CollectionParameter<InvoiceReference>("refs");
getByRefs.ReturnsCollectionFromEntitySet<SIHead>("SIHead");
Run Code Online (Sandbox Code Playgroud)
控制器中的动作方法:
[HttpPost]
[EnableQuery]
[ODataRoute("ByRefs")]
public async Task<IHttpActionResult> ByRefs(ODataActionParameters p)
{
var refs = p["refs"] as InvoiceReference[];
// exception p is null
}
Run Code Online (Sandbox Code Playgroud)
示例json内容发布:
[
{
"InvoiceNumber": "5100011759|9800006622",
"SupplierId": 2
},
{
"InvoiceNumber": "5100012624|9800006635",
"SupplierId": 2
},
{
"InvoiceNumber": "5100012625|9800006636",
"SupplierId": 2
}
]
Run Code Online (Sandbox Code Playgroud)
在我看来,我错过了一些东西或者OData坏了.
在从github获得一些反馈之后(感谢Sam),我得出的结论是OData的工作方式意味着我们必须始终发布一个对象,而不是直接发布一个集合......
我在这里错过了一些微妙/隐含的规则......
我必须提供一个对象(作为容器),而不仅仅是我要发布的数组.我无法直接绑定到ICollection,IList,List或Array IEnumerable出于好奇:为什么这与普通的webAPI不同?WebAPI绑定中的底层绑定框架非常棒.
我不确定这个"奇怪"是否有详细记录,看起来无论我发布什么,我应该总是提供一个对象而不是直接在体内的集合.
发布数组我必须做...
{ "foos": [1,2,3,4] }
Run Code Online (Sandbox Code Playgroud)
..而不是......
[1,2,3,4]
Run Code Online (Sandbox Code Playgroud)
...然后在操作中始终将已发布的集合视为Enumerable ...
Task PostStuff(ODataActionParameters p)
{
var foos = p["foos"] as IEnumerable<Foo>;
...
}
Run Code Online (Sandbox Code Playgroud)
...我很确定这个例子是在某个地方给出的,但我很确定这个要求身体总是包含一个对象不是(我可能是错的).我想这是为了鼓励人们建立强类型的请求体(感觉就像IMO一样好).