How to patch enumerables and guids with OData V4 Delta in Asp.Net.Core 3.1

asp.net-core entity-framework-core odata postman

Question

I am working on a new ASP.NET Core 3.1 API using the Microsoft.AspNetCore.OData nuget v7.3.0 and Microsoft.EntityFrameworkCore v3.1.1

I am using Postman v7.21.0 to test the API.

Everything seems to be working well GET and POST but with PATCH, I only seem to be able to update strings. If I try to update an entity field that is a GUID or an ENUM, it does not do the update and I do not get any kind of error.

If I call HTTP PATCH with the following JSON in the request body;

{
    "@odata.context": "https://localhost:44367/odata/$metadata#Account",
    "AccountName": "Test Account 1"
}

The delta correctly updates the AccountName field, which is a string.

However, if I call HTTP PATCH with the following JSON in the request body;

{
    "@odata.context": "https://localhost:44367/odata/$metadata#Account",
    "OwnerId": "f9d1f8c7-2cbb-4156-0031-08d7d0f9edd5"
}

Where OwnerID is a GUID, I do not get any kind of error but the OwnerId value is not updated in the database.

Similarly,if I call HTTP PATCH with the following JSON in the request body;

{
    "@odata.context": "https://localhost:44367/odata/$metadata#Account",
    "Status": "Inactive"
}

There Status is an ENUM, it also willnot update the database with the change.

In my meta data, the Status is listed as Type="MyApi.Enums.StatusTypes" and the OwnerId is listed as Type="Edm.Guid".

Do I need to include the Type in my request body?

I tried the following;

{
    "@odata.context": "https://localhost:44367/odata/$metadata#Account",
    "@odata.Type": "MyApi.Enums.StatusTypes" 
    "Status": "Inactive"
}

But it still did not update the database.

Here is my Accounts Controller code for the Patch method in my API;

    [ODataRoute("{id}")]
    [Produces("application/json;odata.metadata=minimal")]
    [ProducesResponseType(typeof(AccountModel), Status200OK)]
    [ProducesResponseType(Status204NoContent)]
    [ProducesResponseType(Status400BadRequest)]
    [ProducesResponseType(Status404NotFound)]
    public async Task<IActionResult> Patch(Guid id, [FromBody] Delta<Account> delta)
    {

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var entity = await _context.Accounts.FindAsync(id);
        if (entity == null)
        {
            return NotFound();
        }

        delta.Patch(entity);
        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (RecordExists(id))
            {
                return NotFound();
            }
            throw;
        }

        return Updated(delta);
    }

I could not find any examples of patching GUIDs or ENUMs on the OData.org. All of the data modification examples used strings.

Any ideas?

What am I missing here?

1
0
3/26/2020 2:28:51 PM

Popular Answer

@whiskytangofoxtrot Assuming you're hitting your service from Postman (or equivalent), kindly ensure to include the Enum type annotation in the payload. As follows:

{
    "@odata.context": "{{ServiceRoot}}/$metadata#Accounts/$entity",
    "Id": "3527ba9a-f5aa-4337-b7bb-dfe634b15e57",
    "OwnerId": "3527ba9a-f5aa-4337-b7bb-dfe634b15e57",
    "Status@odata.type": "#NS.AccountStatus",
    "Status": "InActive"
}

Replace NS and {{ServiceRoot}} with the namespace and service root (respectively) specific to your scenario. As for the Guid, you don't need to do anything specific.

Find screenshots of my successful attempt: Request: enter image description here

Result: enter image description here

0
4/7/2020 3:02:31 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow