質問

We are building a simple Bulk API to Get and Push large numbers of records. For the Get, OData seems perfect given it easy support for composing queries (and the fact that it is supported nearly out of the box).
However, I am having serious challenges getting Post of Enumerable working:

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);
    }
}

When I try any upload a couple of MyObject in a Json Array, i get the exception:

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

If I remove the [ODataFormatting, ODataRouting] attributes, then the upload succeeds, but I loose the OData query support.

Solution (sort of) It is actually the [IQueryable] that gives me the queryable support. This attribute gives me most of what I want from the API. The item that is breaking me is the ODataFormatting, which replaces the default formatter with one that does not support collections on POST.

And it appears that the only thing I loose functionally by removing the ODataFormatting are the continuation tokens in the case that there is more than one page of data, and perhaps adherence to the OData specification.

Is this all because OData does not have bulk upload POST in their specification? Is there an alternate that adheres to the OData specification and is supported?


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 }
);
役に立ちましたか?

解決

You need to either use batching Or post an entity and a collection of related entities

But for your scenario (where you just want to add multiple records) seems like batching is the only way to go with OData.

Your solution seem fine, but I would make sure you limit the query capability using Query Limitations. See this link for more details - http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options

The query options give the client a lot of control over the query that is run on the server. In some cases, you might want to limit the available options for security or performance reasons. The [Queryable] attribute has some built in properties for this. Here are some examples.

Allow only $skip and $top, to support paging and nothing else:

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

Allow ordering only by certain properties, to prevent sorting on properties that are not indexed in the database:

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

Allow the “eq” logical function but no other logical functions:

[Queryable(AllowedLogicalOperators=AllowedLogicalOperators.Equal)]

Do not allow any arithmetic operators:

[Queryable(AllowedArithmeticOperators=AllowedArithmeticOperators.None)]

You can restrict options globally by constructing a QueryableAttribute instance and passing it to the EnableQuerySupport function:

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

config.EnableQuerySupport(queryAttribute);
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top