发布IEnumerable(1000条记录)

时间:2014-05-06 05:45:57

标签: asp.net rest asp.net-web-api odata ienumerable

我们正在构建一个简单的批量API来获取和推送大量记录。 对于Get,OData看起来很完美,因为它可以轻松支持编写查询(以及几乎支持开箱即用的事实)。
但是,我正在接受可疑工作岗位的严峻挑战:

public class MyObject
{
    public int MyInt {get;set;}
}

[ODataFormatting, ODataRouting]
public class MyObjectController 
    : ApiController
{
    [Queryable(PageSize=2)]
    public IQueryable<MyObjecct> Get()
    {
        return Ninject.Get<IMyObjectDb>().MyObjects;
    }

    public HttpResponseMessage Post([FromBody] IList<MyObject> leadList)
    {
        return Request.CreateResponse(HttpStatusCode.Created);
    }
}

当我尝试在Json数组中上传几个MyObject时,我得到了例外:

{
-odata.error: {
    code: ""
    -message: {
    lang: "en-US"
    value: "The request is invalid."
  }
    -innererror: {
    message: "objectList : 'ODataFeedDeserializer' does not support Read. "
    type: ""
    stacktrace: ""
  }
}

如果删除[ODataFormatting,ODataRouting]属性,则上传成功,但我放弃了OData查询支持。

解决方案(有点) 实际上[IQueryable]给了我可查询的支持。这个属性给了我大部分我想要的API。 打破我的项目是ODataFormatting,它将默认格式化程序替换为不支持POST上的集合的格式化程序。

看来我删除ODataFormatting的唯一功能就是在存在多个数据页并且可能符合OData规范的情况下继续使用令牌。

这是因为OData在其规范中没有批量上传POST吗? 是否存在符合OData规范并且受支持的替代方案?


Microsoft.AspNet.WebApi.OData.5.1.2
Microsoft.AspNet.WebApi.Client.5.1.2
Newtonsoft.Json.6.0.2
Registration:
// Web API configuration and services
ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<MyObject>("MyObjects");

Microsoft.Data.Edm.IEdmModel model = modelBuilder.GetEdmModel();
config.Routes.MapODataRoute("ODataRoute", "api/v1", model);

// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
   name: "DefaultApi",
   routeTemplate: "api/v1/{controller}/{id}",
   defaults: new { id = RouteParameter.Optional }
);

1 个答案:

答案 0 :(得分:1)

您需要使用批处理 或发布实体和相关实体的集合

但对于您的场景(您只想添加多个记录),似乎批处理是唯一可以使用OData的方法。

您的解决方案似乎很好,但我会确保您使用查询限制来限制查询功能。有关详细信息,请参阅此链接 - http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options

查询选项使客户端能够对服务器上运行的查询进行大量控制。在某些情况下,出于安全性或性能原因,您可能希望限制可用选项。 [Queryable]属性具有一些内置属性。以下是一些例子。

仅允许$ skip和$ top,以支持分页,而不支持其他内容:

[Queryable(AllowedQueryOptions=
    AllowedQueryOptions.Skip | AllowedQueryOptions.Top)]

仅允许按某些属性排序,以防止对未在数据库中编制索引的属性进行排序:

[Queryable(AllowedOrderByProperties="Id")] // comma-separated list of properties

允许“eq”逻辑功能但不允许其他逻辑功能:

[Queryable(AllowedLogicalOperators=AllowedLogicalOperators.Equal)]

不允许任何算术运算符:

[Queryable(AllowedArithmeticOperators=AllowedArithmeticOperators.None)]

您可以通过构造QueryableAttribute实例并将其传递给EnableQuerySupport函数来全局限制选项:

var queryAttribute = new QueryableAttribute()
{
    AllowedQueryOptions = AllowedQueryOptions.Top | AllowedQueryOptions.Skip,
    MaxTop = 100
};

config.EnableQuerySupport(queryAttribute);