Search code examples
asp.net-coreodata

How do I use PATCH with ASP.NET Core and Postman?


On Postman, I'm trying to make a PATCH request to my OData Controller. I think I have it set up correctly, but it's not working. Could someone help?

enter image description here

My controller looks like this:

[Authorize]
public class SMSNotesController : ODataController
{
    private readonly ApplicationDbContext _appDbContext;
    
public SMSNotesController(ApplicationDbContext appDbContext)
    {
        _appDbContext = appDbContext;
    
    }

[EnableQuery]
public async Task<IActionResult> Patch([FromODataUri] long noteID, [FromBody] Delta<SMS_Note> note)
{
    if (!ModelState.IsValid)
     {
        return BadRequest(ModelState);
    }
            var entity = await _appDbContext.SMS_Notes.FindAsync(noteID);
            if (entity == null)
            {
                return NotFound();
            }
            note.Patch(entity);
            try
            {
                await _appDbContext.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                bool SMS_NoteExists = await _appDbContext.SMS_Notes.AnyAsync(a => a.Id == noteID);
                if (!SMS_NoteExists)
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return Updated(entity);
        }
    }

I've registered the ODATA Controller in IModelConfiguration.

        public class OdataModelConfigurations : IModelConfiguration 
    {
        public void Apply(ODataModelBuilder builder, ApiVersion apiVersion)
        {
            builder.EntitySet<SMS_Note>("SMSNotes");


        }
    }

What am I missing? I'm getting 404 Not Found as a response.


Solution

  • After some Googling (there isn't really any good documentation on this), I cobbled this together.

    This is with ASP.NET Core 2.2, and OData 7.5.0.

    Basically:

    • Make sure you provide your PATCH argument with the argument in parenthesis.
    • Add a slash after it.
    • Provide the API version.

    enter image description here

            [AcceptVerbs("PATCH", "MERGE")]
        public async Task<IActionResult> Patch([FromODataUri] long key, Delta<SMS_Note> patch)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var entity = await _appDbContext.SMS_Notes.FindAsync(key);
            if (entity == null)
            {
                return NotFound();
            }
            patch.Patch(entity);
            try
            {
                await _appDbContext.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                bool SMS_NoteExists = await _appDbContext.SMS_Notes.AnyAsync(a => a.Id == key);
                if (!SMS_NoteExists)
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }
    
            return Updated(entity);
        }