ASP.NET WebAPI 2 OData Controller中的自定义GET操作

时间:2014-08-06 15:01:22

标签: c# rest odata asp.net-web-api asp.net-web-api2

我正在使用WebApi2和OData。我想添加自定义操作,并通过GET方法使用它

GET /odata/Providers(2)/DoSth

但我不明白它是如何运作的。这是我的一个控制器的代码:

public class ProvidersController : ODataController
{
    private Entities db = new Entities();

    // GET: odata/Providers
    [Queryable]
    public IQueryable<PROVIDER> GetProviders()
    {
        return db.PROVIDER;
    }
    //... OTHER GENERATED METHODS

    //MY TEST METHOD SHOULD BE inoked: GET /odata/Providers(2)/DoSth
    public int DoSth()
    {
        return 22;
    }
 }

和WebApiConfigFile:

  ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
  builder.EntitySet<PROVIDER>("Providers").EntityType.HasKey(o => o.P_ID);
  //others entities ...

  //my custom action without any parameters, returns int:
  ActionConfiguration getTest = builder.Entity<PROVIDER>().Action("DoSth");
  getTest.Returns<int>();

/ odata / $ metadata

中存在的方法

但无法从网址运行此方法(仍显示404:&#34;未找到与请求URI匹配的HTTP资源&#34;)。

有任何想法如何改善这个问题?

2 个答案:

答案 0 :(得分:5)

在OData中,只能通过POST方法调用操作。所以只需将请求从GET更改为POST。

如果它不起作用,请在控制器中为方法添加一个属性:

[HttpPost]
public int DoSth()
{
    return 22;
}

如果你刚开始玩OData,我建议你从OData V4开始,这是一个OASIS标准。以下是有关操作的示例:https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/ODataActionsSample/

答案 1 :(得分:0)

我以不同的方式解决了这个问题......我不是一个深度潜水的程序员只是一个中间人......但是我确实以任何可能的方式解决问题......

我需要一个无法通过标准$ filter功能处理的搜索功能,我需要返回一个IQueryable,就像任何OData 4控制器一样(少一个get函数)。

首先在我合适的控制器中......我使用了Get“Entity”调用的完全相同的签名并添加了一个参数。

    [EnableQuery]
    public IQueryable<detail> Getdetails([FromODataUri] int key)
    {
        return db.masters.Where(m => m.masterid == key).SelectMany(m => m.details);
    }

    // custom function goes here...
    [EnableQuery]
    public IQueryable<detail> GetSearchDetails([FromODataUri] int key, [FromODataUri] IEnumerable<int> search)
    {
       1) do your own function logic here... mine happens to be a very complex search...
       2) make sure to return iQueryable as result... I use standard linq queries and then the final return is toList() as IQueryable
       3) I also did a simple return search.Count = 0 ? return all results : return queried results.
    }

在WebAPi配置中,这是签名;

1)第一行表示将代码放在MasterController中。 2)第二行告诉我该怎么称呼函数。 3)第三行告诉我要返回什么。 4)第四行告诉我该怎么称呼参数以及它是什么类型...... 5)如果你想避免必须调用“://.../namespace.function(param ='value')”,第五行非常重要。这将删除虚线命名空间约束。见:this

builder.EntityType<master>()
            .Function("GetSearchDetails")
            .ReturnsCollectionFromEntitySet<detail>("details")
            .CollectionParameter<int>("search");

config.EnableUnqualifiedNameCall(unqualifiedNameCall: true);

这种方法解决了我在客户端的许多问题...现在,我可以调用h !! p:// domain / odata / master(n)/ GetSearchDetails(search = [2,10,31])或者如果它是一个字符串数组h !! p:// domain / odata / master(n)/ GetSearchDetails(search = ['two','ten','threeone'])并且它返回一个IQueryable就像调用一样底层实体...但是,增加的好处是所有标准的OData v4功能仍然存在$ filter,$ select ...等...