我们正在构建一个简单的批量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 }
);
答案 0 :(得分:1)
您需要使用批处理 或发布实体和相关实体的集合
但对于您的场景(您只想添加多个记录),似乎批处理是唯一可以使用OData的方法。
您的解决方案似乎很好,但我会确保您使用查询限制来限制查询功能。有关详细信息,请参阅此链接 - http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options
查询选项使客户端能够对服务器上运行的查询进行大量控制。在某些情况下,出于安全性或性能原因,您可能希望限制可用选项。 [Queryable]属性具有一些内置属性。以下是一些例子。
[Queryable(AllowedQueryOptions=
AllowedQueryOptions.Skip | AllowedQueryOptions.Top)]
[Queryable(AllowedOrderByProperties="Id")] // comma-separated list of properties
[Queryable(AllowedLogicalOperators=AllowedLogicalOperators.Equal)]
[Queryable(AllowedArithmeticOperators=AllowedArithmeticOperators.None)]
var queryAttribute = new QueryableAttribute()
{
AllowedQueryOptions = AllowedQueryOptions.Top | AllowedQueryOptions.Skip,
MaxTop = 100
};
config.EnableQuerySupport(queryAttribute);