I am working on an ASP.NET Core Web API where I need to apply JSON Patch operations to update entities. The problem I'm encountering is that after applying the JSON Patch, the laboId and analyseId fields are being set to 0 instead of the correct values that I provided.
Problem Details: Entities: I have entities such as PcpsModel, RepartitionParDR, RepartitionParService, and RepartitionMensuelle. Patch Request:
[
{
"op": "add",
"path": "/RepartitionParDRs/-",
"value": {
"NiveauInterventionId": 1,
"codeProduit": "string",
"laboId": 1,
"analyseId": 1,
"determinationId": [1],
"TotalAffecte": 25
}
},
{
"op": "add",
"path": "/RepartitionParDRs/-",
"value": {
"NiveauInterventionId": 1,
"codeProduit": "string",
"laboId": 1,
"analyseId": 2,
"determinationId": [1],
"TotalAffecte": 25
}
}
]
Controller Code:
[HttpPatch("{id}")]
[Consumes("application/json-patch+json")]
public async Task<IActionResult> PartialUpdate(int id, [FromBody] JsonPatchDocument<PcpsModelDto> patchDoc)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var pcps = await _repository.GetByIdAsync(id);
_logger.LogInformation("Before patch application, RepartitionParDRs: {RepartitionParDRs}", JsonConvert.SerializeObject(pcps.RepartitionParDRs));
if (pcps == null) return NotFound();
var pcpsDto = _mapper.Map<PcpsModelDto>(pcps);
// Make sure you are applying the patch correctly
patchDoc.ApplyTo(pcpsDto, ModelState);
if (!ModelState.IsValid)
{
_logger.LogError("Model state is invalid after applying JSON patch: {ModelStateErrors}", JsonConvert.SerializeObject(ModelState));
return BadRequest(ModelState);
}
foreach (var repDR in pcpsDto.RepartitionParDRs)
{
bool laboId = await _analyseLaboService.ValidateLaboId(repDR.laboId);
bool analyseId = await _analyseLaboService.ValidateAnalyseId(repDR.analyseId);
bool determinationsAreValid = repDR.determinationId != null &&
await Task.WhenAll(repDR.determinationId.Select(id => _analyseLaboService.ValidateDeterminationId(id)))
.ContinueWith(results => results.Result.All(v => v));
if ( !laboId || !analyseId || !determinationsAreValid)
{
return BadRequest($"Validation failed for one or more IDs in RepartitionParDRs for LaboId: {repDR.laboId}, AnalyseId: {repDR.analyseId}.");
}
bool codeProduitIsValid = pcpsDto.ProduitsPcps.Any(p => p.Code == repDR.codeProduit);
if (!codeProduitIsValid)
{
return BadRequest($"Invalid codeProduit: {repDR.codeProduit}. No corresponding produit found in ProduitsPcps.");
}
}
foreach (var produitPcps in pcpsDto.ProduitsPcps)
{
bool produitExists = await _produitService.ValidateProduitExists(produitPcps.produitId);
if (!produitExists)
{
return BadRequest($"Invalid produit_id: {produitPcps.produitId}. No corresponding produit found.");
}
}
// Validate TotalAffecte
int totalAffecteSum = pcpsDto.RepartitionParDRs.Sum(r => r.TotalAffecte);
if (totalAffecteSum != pcpsDto.TotalPrevisionnel)
{
return BadRequest("The total of TotalAffecte must be equal to TotalPrevisionnel.");
}
foreach (var repDR in pcpsDto.RepartitionParDRs)
{
int totalServiceAffecte = repDR.RepartitionParServices.Sum(s => s.TotalAffecteService);
if (totalServiceAffecte != repDR.TotalAffecte)
{
return BadRequest($"The total of TotalAffecteService for DRId {repDR.Id} must be equal to its TotalAffecte.");
}
}
_mapper.Map(pcpsDto, pcps);
await _repository.UpdateAsync(pcps);
return Ok(_mapper.Map<PcpsModelDto>(pcps));
}
Configuration: JSON Serializer Settings in Program.cs:
builder.Services.AddControllers().AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
The laboId and analyseId values are correctly provided in the patch request, but they are being set to 0 when the patch is applied. The validation service is failing because it receives 0 instead of the correct ID values.
What I've Tried: Verified that the laboId and analyseId values exist in the database. Added logging to check values after applying the patch. Checked JSON serializer settings to ensure reference loop handling is ignored.
Questions: What could be causing the laboId and analyseId to be set to 0 after applying the JSON Patch? How can I ensure that the correct values are maintained and passed to the validation service?
