Patch does not update the data
See original GitHub issuePatch does not update the data
We are building an API in AspNetCore (without a mapping for the entities). While using the JsonApiController
, the Get, Post en Delete work fine. However, the Patch does not work.
I have override the PatchAsync, and the application get into that breakpoint, but the entity remains empty and the AttributesToUpdate
remains an empty list.
I seems as if this code should work (even without the overriding method in the controller). What am I missing, or what could I test?
------ see (parts of) the code below. ------
Key | Value |
---|---|
Type | PATCH |
URL | http://localhost:62596/patchtable/2 |
Content-Type | application/vnd.api+json |
Body | {“data”: {“type”: “patchtable”,“id”: 2,“attributes”: {“text”: “A new value”}}} |
The code inside the PatchtableController.cs
. In comments I’ve added some of the findings I’ve made when trying to debug what was going on.
public class PatchtableController : JsonApiController<Patchtable>
{
private IJsonApiContext _jsonApiContext;
public PatchtableController(
IJsonApiContext jsonApiContext,
IResourceService<Patchtable, int> resourceService) :
base(jsonApiContext, resourceService)
{
_jsonApiContext = jsonApiContext;
}
[HttpPatch("{id}")]
public override async Task<IActionResult> PatchAsync(int id, [FromBody] Patchtable entity)
{
// _jsonApiContext.AttributesToUpdate.Count -> 0;
// Patchtable entity -> null
return await base.PatchAsync(id, entity);
}
}
The test-model is just a simple without any relations. See the Patchtable .cs
, the PatchtableTypeConfiguration
below and part of our ApplicationDbContext.cs
below.
public class Patchtable : Identifiable
{
[Attr("text")]
[Required]
public string Text { get; set; }
}
public class PatchtableTypeConfiguration : IEntityTypeConfiguration<Patchtable>
{
public void Configure(EntityTypeBuilder<Patchtable> builder)
{
builder.HasKey(x => x.Id);
builder.Property(x => x.Text)
.IsRequired();
}
}
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions options) : base(options) { }
public DbSet<...> ...{ get; set; }
public DbSet<Patchtable> Patchtables { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new ...TypeConfiguration());
modelBuilder.ApplyConfiguration(new PatchtableTypeConfiguration());
}
}
See the Startup.cs
below. I’ve tested the application with adding the option options.EnableOperations = true
, without result.
public void ConfigureServices(IServiceCollection services)
{
string connection = Configuration["ConnectionStrings:DefaultConnection"];
string assemblyName = Assembly.GetAssembly(typeof(ApplicationDbContext)).FullName;
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
connection,
sqlServerOption => sqlServerOption.MigrationsAssembly(assemblyName)));
services.AddJsonApi<ApplicationDbContext>();
services.AddOpenApiDocument(settings =>
settings.SchemaType = SchemaType.OpenApi3);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
…
Environment
- JsonApiDotNetCore version: 3.1.0
- Microsoft.AspNetCore.App version: 2.2.0
- Microsoft.EntityFrameworkCore.SqlServer version: 2.2.4
- Microsoft.NETCore.App version: 2.2.0
Issue Analytics
- State:
- Created 4 years ago
- Comments:7 (4 by maintainers)
Top GitHub Comments
Thanks for the feedback, it helped me in the right direction 😃
Although the name of controller seems to have little consequences, apart from the URL.
I’ve updated my test-project and will leave it there for a while. Feel free to pick anything from it should you wish to add another example to your list of example-projects. In the readme I’ve added two lessons-learned, the things we probably did wrong while trying to figure out why Patch did not work. https://github.com/incomudro/ApiTestProject
Lesson 1: Case-sensitivity For PATCH, the attribute is case-sensitive and should be the same as defined in the model. As the attribute is not case-sensitive for POST, this mistake was probably overlooked once or twice.
Lesson 2: Type The type defined in the PATCH, should be the same as the name for the
DbSet<T>
. Thus when theDbSet<Fruit>
is ‘Fruits’, the type provided in the body of the PATCH should be ‘fruits’ as well.Know that the type is not case-sensitive and both
"type": "fruits"
and"type": "Fruits"
will work.@incomudro Hi, be carefull with your naming convention - your Context use Patchables and your type is “patchable”. The problem with this line
services.AddJsonApi<ApplicationDbContext>();
is, that your application must use same convention in controller layer as you use in your ApplicationDbContext. And there is another hidden convention with this - your controller name defines “type” (BlogController => type=“blog”, BlogsController => type=“blogs”)First approach to fix- pluralize
Second approach to fix - singularize
DbSet<Patchtable> Patchtables
->DbSet<Patchtable> Patchtable