JSON retrieve with only some elements of its model

0

In my backend I have a model defined this way:

    using System;
    using System.Collections.Generic;
    
    namespace App.API.Models
    {
        public class Situation
        {
            public int Id { get; set; }
            public string Description { get; set; }
            public bool IsMain { get; set; }
            public int UserId { get; set; }
            public bool IsApproved { get; set;}

        }
    }

In my frontend I have a service with this function defined:

rejectSituation(id: number) {
  return this.http
  .put(
    this.baseUrl + 'Situation/' + id,
    {
      "id": id,
      "isApproved": "false" 
    }
  );
}

As far as I only want to change the IsApproved variable of the frontend model, I only send this with my function service. And, I call this service from the .ts file from my component:

   approveSituation(situacionId: number) {
     this.situacionesService.approveSituation(situacionId).subscribe(() => {
      // 1) Searches for the Id in the array 
      let index = this.situaciones.findIndex(p => p.id === this.situacion.id);
      // 2) Put this in situation's array
      this.situaciones[index].isApproved = true;
     }, error => {
      console.log(error);
     });
  }

But unfortunately I found this error at the end:

Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
     ---> Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 19: 'FOREIGN KEY constraint failed'.
       at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
       at Microsoft.Data.Sqlite.SqliteDataReader.NextResult()
       at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReader(CommandBehavior behavior)
       at Microsoft.Data.Sqlite.SqliteCommand.ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
       at Microsoft.Data.Sqlite.SqliteCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
       --- End of inner exception stack trace ---
       at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(DbContext _, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
       at App.API.Data.VVRepository.SaveAll() in D:\Project6\App\App.API\Data\VVRepository.cs:line 181
       at App.API.Helpers.LogUserActivity.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) in D:\Project6\App\App.API\Helpers\LogUserActivity.cs:line 21
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
    --- End of stack trace from previous location where exception was thrown ---
       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
       at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
       at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
       at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
       at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
    
    HEADERS
    =======
    Connection: keep-alive
    Content-Type: application/json
    Accept: application/json, text/plain, */*
    Accept-Encoding: gzip, deflate, br
    Accept-Language: es,es-ES;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
    Authorization: Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIxIiwidW5pcXVlX25hbWUiOiJMb2xhIiwicm9sZSI6IkFkbWluIiwibmJmIjoxNTk4NzE1NjEyLCJleHAiOjE1OTg4MDIwMTIsImlhdCI6MTU5ODcxNTYxMn0.WHy68UGhoJfN1Z8REEDe3FgltNdMf04JZrQ9694rMvq2Re62NBLR71pKuDPghQu4r5I-XzCDearzz25H1Jo9yQ
    Host: localhost:5000
    Referer: http://localhost:4200/admin
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36 Edg/85.0.564.41
    DNT: 1
    Origin: http://localhost:4200
    Content-Length: 25
    Sec-Fetch-Site: same-site
    Sec-Fetch-Mode: cors
    Sec-Fetch-Dest: empty

I think...It's due to the JSON structure I'm sending from the frontend to the backend, because the model needs all its items. But the frontend is sending a JSON that does not match the order. In other words, if I send 'id' and 'isApproved' without the other items: Description, IsMain and UserId... this is not going to work. But...How to change that item in the backend without sending information about the other items?

Trying this...leads to failure....Why?

c#
json
angular
frontend
backend
asked on Stack Overflow Aug 29, 2020 by Eterno

1 Answer

0

You should make sure to send the model with values assigned to all the properties. If that is not possible, you should retrieve the data object from database first (assuming that model has Id property set which is PK of the table), set it's properties from the model properties values which are not null and save the data object back to the database.

#Chetan is right, you need to send the complete model of PUT. If you want to just send the changes in the model, you'll need to use the PATCH verb and a JsonPatch document. jsonpatch.com – Darren Street yesterday

That were the solutions! Thanks!

answered on Stack Overflow Sep 5, 2020 by Eterno

User contributions licensed under CC BY-SA 3.0