I am creating an ASP.NET Core single page application using react.js. I am getting a 404 Not found when for POST within customer. I have tried using postman and passing through the appropriate data but having no luck finding the issue. I am not too experienced with this, if am I missing anything or you want to see more code let me know. Thanks!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using KCA.Core.Exceptions;
using KCA.Core.Interfaces;
using KCA.Core.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace KCA.WebApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class CustomerController : ControllerBase
{
private readonly ICustomerServices _customerServices;
public CustomerController(ICustomerServices customerServices)
{
_customerServices = customerServices;
}
// GET: api/Customer
[HttpGet]
public async Task<ActionResult<IEnumerable<Customer>>> GetCustomers()
{
try
{
var customers = await _customerServices.GetAllAsync();
return Ok(customers);
}
catch (Exception ex)
{
return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
}
}
// GET: api/Customer/{id}
[HttpGet("{id}")]
public async Task<ActionResult<Customer>> GetCustomer(Guid id)
{
try
{
var customer = await _customerServices.GetByIdAsync(id);
return Ok(customer);
}
catch (NotFoundException ex)
{
return NotFound(ex.Message);
}
catch (BadRequestException ex)
{
return BadRequest(ex.Message);
}
catch (Exception ex)
{
return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
}
}
// POST: api/Customer
[HttpPost]
public async Task<ActionResult<Customer>> PostCustomer([FromBody] Customer customer)
{
try
{
await _customerServices.AddAsync(customer);
return CreatedAtAction(nameof(GetCustomer), new { id = customer.Id }, customer);
}
catch (BadRequestException ex)
{
return BadRequest(ex.Message);
}
catch (ConflictException<Customer> ex)
{
return Conflict(ex.Message);
}
catch (Exception ex)
{
return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
}
}
// PUT: api/Customer/{id}
[HttpPut("{id}")]
public async Task<IActionResult> PutCustomer(Guid id, [FromBody] Customer customer)
{
if (id != customer.Id)
{
return BadRequest("Customer ID mismatch.");
}
try
{
await _customerServices.UpdateAsync(customer);
return NoContent();
}
catch (NotFoundException ex)
{
return NotFound(ex.Message);
}
catch (BadRequestException ex)
{
return BadRequest(ex.Message);
}
catch (Exception ex)
{
return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
}
}
// DELETE: api/Customer/{id}
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteCustomer(Guid id)
{
try
{
await _customerServices.DeleteAsync(id);
return NoContent();
}
catch (NotFoundException ex)
{
return NotFound(ex.Message);
}
catch (BadRequestException ex)
{
return BadRequest(ex.Message);
}
catch (Exception ex)
{
return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
}
}
}
}
This is the Program.cs
as I know there could be an issue within it
using KCA.Infrastructure;
using KCA.Core.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using KCA.Infrastructure.Data;
using KCA.Core.Interfaces;
using KCA.Core.Services;
namespace KCA.Web
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
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)
{
var connectionString = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<KCAContext>(options =>
options.UseSqlServer(connectionString));
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddDefaultIdentity<Employee>(options => options.SignIn.RequireConfirmedAccount = false)
.AddEntityFrameworkStores<KCAContext>()
.AddDefaultTokenProviders();
services.AddIdentityServer()
.AddApiAuthorization<Employee, KCAContext>();
//Add Services
services.AddScoped<IKCAContext, KCAContext>();
services.AddScoped<ICarService, CarServices>();
services.AddScoped<ICustomerServices, CustomerServices>();
services.AddScoped<IEmployeeServices, EmployeeServices>();
services.AddScoped<IPartsService, PartsService>();
services.AddScoped<IJobServices, JobServices>();
// Add CORS policy
services.AddCors(options =>
{
options.AddPolicy("AllowAll", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
services.AddControllersWithViews();
services.AddRazorPages();
}
// 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.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();
app.UseCors("AllowAll");
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
endpoints.MapRazorPages();
endpoints.MapFallbackToFile("index.html");
});
}
}
}
I have tried using Postman and passing through the appropriate data but still getting a 404 error
In Postman
POST https://localhost:44401//api/Customer
Body: (JSON)
{
"Id": "b63da63d-5fd5-4b5f-8e33-4d4e7c9db927",
"FirstName": "John",
"LastName": "Doe",
"ContactNumber": "555-123-4567",
"Email": "[email protected]",
"Address": "123 Main St",
"Postcode": "12345"
}
EDIT: this is the customer model encase it is something I am missing
using KCA.Core.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace KCA.Core.Models
{
public class Customer
{
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[Phone]
public string ContactNumber { get; set; }
[EmailAddress]
public string Email { get; set; }
public string Address { get; set; }
public string Postcode { get; set; }
//Relational data
public virtual ICollection<Car> Cars { get; set; }
public virtual ICollection<Job> Jobs { get; set; }
}
}
4
Answers
https://localhost:44401/api/Customer/PostCustomer
This should be the url with method POST and a body.
In Program.cs file add services.AddControllers() after services.AddControllersWithViews()
Example:
services.AddControllersWithViews();
services.AddControllers();
Api controller supports only attribute routing, no any ancient REST, or remove ApiController attribute
so fix the routes
and url
You can try to post to http://localhost:44401/api/Customer/PostCustomer url. Problem could be https.