0

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?

1 Answer 1

0

Please set 2 breakpoint in these 2 line.

enter image description here

Make sure the values of laboId and analyseId are passed to backend correctly.

And I guess the 0 are from your _analyseLaboService. If _analyseLaboService.ValidateLaboId return false, then the value of laboId will be 0.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.