【问题标题】:.Net WebApi OData Actions that return an Queryable返回 Queryable 的 .Net WebApi OData 操作
【发布时间】:2013-06-13 19:37:10
【问题描述】:

我想实现类似于以下所述的 RateProduct 操作:http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-actions

在该教程中,它被定义为:

[HttpPost]
public int RateProduct([FromODataUri] int key, ODataActionParameters parameters) 
{ 
    // ...
}

ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Product>("Products");

// New Code
ActionConfiguration rateProduct = modelBuilder.Entity<Product>().Action("RateProduct");
rateProduct.Parameter<int>("Rating");
rateProduct.Returns<int>();

但是,我有一个 Location 实体的用例,它足够聪明,可以返回它周围某个半径内的其他位置。大致应该是这样的:

[HttpPost]
public IQueryable<Location> GetLocationsWithinRadius([FromODataUri] int key, ODataActionParameters parameters) 
{ 
    // Get the Location instance intended to be the center of the radius by using the key
    // Do a radius search around it using (int)parameters["radius"] as the radius
    // return the IQueryable<Location> of all location found within that radius
}

ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Location>("Locations");

// New Code
ActionConfiguration getLocations = modelBuilder.Entity<Location>().Action("GetLocationsWithinRadius");
getLocations.Parameter<int>("radius");
getLocations.Returns<IQueryable<Location>>();

我很乐意让它工作,但当返回类型为 IQueryable&lt;Location&gt; 时,它目前不起作用。如果返回类型是像 int 这样的原始类型,那么它可以工作,否则当我在 fiddler 中创建帖子时会出现以下错误(帖子类似于http://localhost:2663/odata/Locations(2112)/GetLocationsWithinRadius,请求正文是{radius: 50}):

{
  "odata.error":{
    "code":"","message":{
      "lang":"en-US","value":"An error has occurred."
    },"innererror":{
      "message":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; odata=minimalmetadata; streaming=true; charset=utf-8'.","type":"System.InvalidOperationException","stacktrace":"","internalexception":{
        "message":"The related entity set could not be found from the OData path. The related entity set is required to serialize the payload.","type":"System.Runtime.Serialization.SerializationException","stacktrace":"   at System.Web.Http.OData.Formatter.Serialization.ODataFeedSerializer.WriteObject(Object graph, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)\r\n   at System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.<>c__DisplayClassa.<WriteToStreamAsync>b__9()\r\n   at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token)"
      }
    }
  }
}

有可能做我想要完成的事情吗?如果是,我敢问返回的IQueryable&lt;Location&gt; 是否可以与 odata 参数组合...(那会很好)?

谢谢

【问题讨论】:

  • 我看到你的实体集类型是Product。这应该是Location吗?你还有更多的错误细节吗?如果是,你能分享一下吗?这会很有帮助。您可以通过config.IncludeErrorDetailPolicy=IncludeErrorDetailPolicy.Always获取更多详细信息。
  • 是的 - 我刚刚解决了这个问题 - 我的错。我用 SO 手写代码,而不是复制和粘贴。我也在编辑帖子以显示完整的错误。

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


【解决方案1】:

您的操作配置似乎不正确。尝试以下方法,看看是否有效:

//getLocations.Returns<IQueryable<Location>>();
getLocations.ReturnsCollectionFromEntitySet<Location>("Locations");

【讨论】:

  • Ehm - 我不知道我是如何忽略这一点的。像魅力一样工作。我真的很感谢你的帮助!谢谢
  • 嗯,我试过了,但它可以工作,如果应用 EnableQuery,它似乎会进入 406 错误......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
  • 2015-04-10
  • 2015-05-22
  • 1970-01-01
  • 2013-05-26
  • 2020-01-12
相关资源
最近更新 更多