Reputation: 1
I am working on an ASP.NET Core Web API project and need to update multiple columns for multiple rows within a single HTTP PATCH request. I am familiar with using JsonPatchDocument to update a single object, but I am unsure how to extend this to handle updating multiple objects in the same table at once.
Here is what I am trying to achieve:
I have a table with multiple rows that need to be updated. Each row can have multiple columns that need to be changed. I want to send a single PATCH request to update these rows and columns.
public class MyEntity
{
public int Id { get; set; }
public string Name { get; set; }
public string Code { get; set; }
public DateTime CountDate { get; set; }
}
The collection i am sending by Postman:
[
{
"id": 4,
"changes": {
"Name": "Test",
"Code": "ICO3",
"CountDate": "2024-06-25T11:00:00"
}
},
{
"id": 6,
"changes": {
"Name": "Test",
"Code": "ICO9",
"CountDate": "2024-06-25T11:00:00"
}
}
]
the normal Patch method for handling one request:
[HttpPatch("{id}")]
public IActionResult PatchEntity(int id, [FromBody] JsonPatchDocument<MyEntity> patchDoc)
{
if (patchDoc == null)
{
return BadRequest();
}
var entity = _context.MyEntities.Find(id);
if (entity == null)
{
return NotFound();
}
patchDoc.ApplyTo(entity, ModelState);
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_context.SaveChanges();
return NoContent();
}
custom Patch that i made:
[HttpPost("Batch")]
public virtual async Task<IActionResult> Batch([FromBody] Dictionary<int, Delta<T>> objs)
{
var errors = new List<string>();
var responses = new List<object>();
foreach (var kvp in objs)
{
try
{
// Ensure entity exists
var entity = await _context.T.FindAsync(kvp.Key);
if (entity == null)
{
errors.Add($"Object with ID {kvp.Key} not found.");
continue;
}
// Apply patch
kvp.Value.Patch(entity);
// Validate model state
if (!TryValidateModel(entity))
{
errors.Add($"Invalid model state for object with ID {kvp.Key}.");
continue;
}
// Save changes
await _context.SaveChangesAsync();
responses.Add(new { Id = kvp.Key, Success = true });
}
catch (Exception ex)
{
errors.Add($"Failed to patch object with ID {kvp.Key}: {ex.Message}");
}
}
if (errors.Any())
{
return BadRequest(errors);
}
return Ok(responses);
}
when i check the delta object, the _changedProperties is always 0
Question:
How can I extend this approach to handle a single PATCH request that updates multiple rows and multiple columns in the same table? Ideally, I would like to ensure that all updates are applied in a single transaction.
Any advice or examples on how to achieve this would be greatly appreciated!
Upvotes: 0
Views: 93