First, I want to say [HttpGet], [HttpGet("{id}")], and [HttpPost] is working correctly. However I'm running into a challenge with [HttpPut], and almost everywhere I look, the solution is to return without a status code.
I'm using visual studio 2019 with a project type of "ASP.NET Core Web Application" and "API" (ASP.NET Core 3.1).
I'm also using a secondary project in the same visual studio solution with the type(C#) "Class Library (.NET Standard)".
I'm using Postman to test the http request calls.
The following (Additional) NuGet Packages are required to be installed:
- Microsoft.EntityFrameworkCore
- Microsoft.EntityFrameworkCore.InMemory
- System.ComponentModel.Annotations
The Solution Explorer:
There is a lot of code to cover with the .net core, and I will show it all here (as far as what has changed).
The Project "CoreStudy.Api" Code:
Startup.cs
using CoreStudy.Data.Context;
using CoreStudy.Data.Repository;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace CoreStudy.Api
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddScoped<PeopleRepository>(); // add this line
services.AddDbContext<PersonContext>(opt => opt.UseInMemoryDatabase("PeopleInventory")); // add this line, requires NuGet package "Microsoft.EntityFrameworkCore.InMemory"
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
PeopleController.cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using CoreStudy.Data.Repository;
using CoreStudy.Data.Models;
using Microsoft.AspNetCore.Http;
namespace CoreStudy.Api.Controllers
{
[Route("people")]
[ApiController]
public class PeopleController : ControllerBase
{
private readonly PeopleRepository _repository;
public PeopleController(PeopleRepository repository)
{
_repository = repository;
}
[HttpGet]
[ProducesResponseType(typeof(List<PersonModel>), StatusCodes.Status200OK)]
public IActionResult GetPeople()
{
return Ok(_repository.GetPeople());
}
[HttpGet("{id}")]
[ProducesResponseType(typeof(PersonModel), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult GetPersonById(int id)
{
var person = _repository.GetPersonById(id);
if (person == null)
{
return NotFound();
}
return Ok(person);
}
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> AddPersonAsync([FromBody] PersonModel person)
{
if((_repository.GetPersonById(person.id) != null) || String.IsNullOrWhiteSpace(person.name))
{
return BadRequest();
}
int peopleAdded = await _repository.AddPersonAsync(person);
return CreatedAtAction(nameof(GetPersonById), new { person.id }, person);
}
[HttpPut]
[ProducesResponseType(typeof(PersonModel), StatusCodes.Status202Accepted)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> ChangePersonNameByIdAsync([FromBody] PersonModel person)
{
if (_repository.GetPersonById(person.id) == null)
{
return NotFound();
}
else if (String.IsNullOrWhiteSpace(person.name))
{
return BadRequest();
}
PersonModel updatedPerson = await _repository.ChangePersonNameAsync(person);
return Ok(updatedPerson);
}
}
}
The Project "CoreStudy.Data" Code:
PersonContext.cs
using Microsoft.EntityFrameworkCore;
using CoreStudy.Data.Models;
namespace CoreStudy.Data.Context
{
public class PersonContext : DbContext
{
public PersonContext(DbContextOptions<PersonContext> options) : base(options)
{
}
public DbSet<PersonModel> people { get; set; }
}
}
PersonModel.cs
using System.ComponentModel.DataAnnotations;
namespace CoreStudy.Data.Models
{
public class PersonModel
{
public int id { get; set; }
[Required]
public string name { get; set; }
public string position { get; set; }
public PersonModel() { }
public PersonModel(string name, string position)
{
this.name = name;
this.position = position;
}
public PersonModel(int id, string name, string position)
{
this.id = id;
this.name = name;
this.position = position;
}
}
}
PeopleRepository.cs
using System.Collections.Generic;
using CoreStudy.Data.Models;
using CoreStudy.Data.Context;
using System.Linq;
using System.Threading.Tasks;
namespace CoreStudy.Data.Repository
{
public class PeopleRepository
{
private readonly PersonContext context;
public PeopleRepository(PersonContext context)
{
this.context = context;
if (context.people.Count() == 0)
{
context.people.AddRange(
new PersonModel
{
name = "shaggy",
position = "screwball"
},
new PersonModel
{
name = "scooby",
position = "screwball dog"
},
new PersonModel
{
name = "fred",
position = "leader"
},
new PersonModel
{
name = "velma",
position = "smart one"
},
new PersonModel
{
name = "daphne",
position = "popular one"
});
context.SaveChanges();
}
}
public List<PersonModel> GetPeople()
{
return context.people.ToList();
}
public PersonModel GetPersonById(int id)
{
PersonModel person = context.people.Find(id); // null if not found
return person;
}
public async Task<int> AddPersonAsync(PersonModel person)
{
int rowsAffected = 0;
context.people.Add(person);
rowsAffected = await context.SaveChangesAsync();
return rowsAffected;
}
public async Task<PersonModel> ChangePersonNameAsync(PersonModel person)
{
context.people.Update(person);
await context.SaveChangesAsync();
return GetPersonById(person.id);
}
}
}
When trying to make a PUT request with postman, I get the following error:
The problem is either in one of these two snippets:
public async Task<PersonModel> ChangePersonNameAsync(PersonModel person)
{
context.people.Update(person); // I thought Update() would be best used here, but not sure
await context.SaveChangesAsync();
return GetPersonById(person.id);
}
[HttpPut]
[ProducesResponseType(typeof(PersonModel), StatusCodes.Status202Accepted)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> ChangePersonNameByIdAsync([FromBody] PersonModel person)
{
if (_repository.GetPersonById(person.id) == null)
{
return NotFound();
}
else if (String.IsNullOrWhiteSpace(person.name))
{
return BadRequest();
}
PersonModel updatedPerson = await _repository.ChangePersonNameAsync(person);
return Ok(updatedPerson); // not sure if I should be using Ok() for a PUT
}
If anyone could help me resolve this, myself (and I'm sure much of the internet) would thank you.

