Skip to content

OData.Client DataServiceContext BulkUpdate() Always Uses Protocol Version 4.01 #3004

@AlpineJBoehnen

Description

@AlpineJBoehnen

In Microsoft.OData.Client 7.21.3 the Microsoft.OData.Client.DataService.Context.BulkUpdate() method appears to force the OData-Version header to 4.01 regardless of the
maxProtocolVersion provided to the DataServiceContext constructor. I am using Microsoft.AspNetCore.OData 8.2.5 on my server, and out of the box it cannot deal with this protocol of OData for bulk updates (Specifically the DeltaSet<T> parameter of my entity set patch action is always null). In Postman if I send an identical request as the client to the server but with the OData-Version header set to 4.0 the server handles this without issue. My questions are as follows:

  • How do I send a bulk update request to an OData 4.0 server with Microsoft.OData.Client?
  • Why does BulkUpdate() force the protocol version to 4.01?
  • Is this an issue with my client or my server (i.e. do I need to direct this issue at Microsoft.AspNetCore.OData)?

I should also note that I am using OData Connected Service on my client for code generation, but I am not sure this is relevant.

Assemblies affected

  • Microsoft.OData.Client 7.21.3
  • Microsoft.AspNetCore.OData 8.2.5

Reproduce steps

I implemented Sample Request 1 from the OData Client Bulk Update Operations examples on my client.
And implemented an endpoint on my server to "patch a collection of entities" from this Microsoft.AspNetCore.OData tutorial.

Note: I modified the client example to work with the Shape, Circle, Rectangle models from the server example.

Client code:

Default.Container context = new Default.Container(new Uri("https://localhost:7092/odata/"), Microsoft.OData.Client.ODataProtocolVersion.V4);

Shape s1 = new Shape { Id = 1, Area = 10 };
context.AddToShapes(s1);

Shape s2 = new Shape { Id = 2, Area = 20 };
context.AddToShapes(s2);

context.BulkUpdate(s1, s2); // fails

Server code:

// Program.cs
var builder = WebApplication.CreateBuilder(args);
var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Shape>("Shapes");

builder.Services.AddControllers()
    .AddOData(opts =>
    {
        opts.EnableQueryFeatures().AddRouteComponents("odata", modelBuilder.GetEdmModel());
    });
// ShapesController.cs
public class ShapesController : ODataController
{
    private static List<Shape> shapes = new List<Shape>
    {
        new Rectangle { Id = 1, Length = 7, Width = 4, Area = 28 },
        new Circle { Id = 2, Radius = 3.5, Area = 38.5 },
        new Rectangle { Id = 3, Length = 8, Width = 5, Area = 40 }
    };

    public async Task<ActionResult> Patch([FromBody] DeltaSet<Shape> deltaSet)
    {
        if (deltaSet == null)
        {
            return BadRequest();
        }

        foreach (Delta<Shape> delta in deltaSet)
        {
            if (delta.TryGetPropertyValue("Id", out object idAsObject))
            {
                var shape = shapes.SingleOrDefault(d => d.Id.Equals(idAsObject));
                delta.Patch(shape);
            }
        }

        return Ok();
    }
}

Expected result

The BulkUpdate() method would succeed on the client, and the DeltaSet<T> parameter on the server would not be null when the action executes.

Actual result

The DeltaSet<T> parameter is null when the server action executes, meaning the server returns BadRequest and the client update operation fails.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions