I have an ASP.NET Core project with React as the framework.
I use the following model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace drivingSchoolManagement.Models
{
[Serializable]
public class Customers
{
public int Id { get; set; }
public string First_name { get; set; }
public string Last_name { get; set; }
public string Address { get; set; }
public string Zip { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public bool Is_active { get; set; }
}
}
And the following Controller:
using drivingSchoolManagement.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace drivingSchoolManagement.Controllers
{
[ApiController]
[Route("[controller]")]
[Produces("application/json")]
public class CustomersController : ControllerBase
{
private readonly ILogger<CustomersController> _logger;
private readonly DatabaseConnection _dbConnection;
public CustomersController(ILogger<CustomersController> logger, DatabaseConnection dbConnection)
{
_logger = logger;
_dbConnection = dbConnection;
}
[HttpGet]
public JsonResult Get()
{
return new JsonResult(_dbConnection.GetAllCustomers());
}
}
}
In my React component Customers.js I want to output the data I get, for this I wrote the following:
import React, { Component } from 'react';
export class Customers extends Component {
static displayName = Customers.name;
constructor(props) {
super(props);
this.state = { customers: [] };
this.getCustomers();
}
async getCustomers() {
try {
const response = await fetch('customers', {
headers: {
Accept: 'application/json',
},
});
console.log(response);
if (!response.ok) {
throw new Error(response.statusText);
}
const data = await response.json();
this.setState({ customers: data });
} catch (error) {
console.log(error);
}
}
render() {
const customers = this.state.customers.map(customer => {
return (
<div key={customer.id}>
<p>ID: {customer.id}</p>
<p>First name: {customer.first_name}</p>
<p>Last name: {customer.last_name}</p>
<p>Address: {customer.address}</p>
<p>Zip: {customer.zip}</p>
<p>Phone: {customer.phone}</p>
<p>Email: {customer.email}</p>
<p>Is active: {customer.is_active ? 'Yes' : 'No'}</p>
</div>
);
});
return (
<div>
<h1>Customers</h1>
{customers}
</div>
);
}
}
Also in my DatabaseConnection.cs I have folling:
public List<Customers> GetAllCustomers()
{
List<Customers> customers = new List<Customers>();
using (NpgsqlConnection connection = OpenConnection())
{
string query = "SELECT * FROM customers";
NpgsqlCommand command = new NpgsqlCommand(query, connection);
using (NpgsqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
customers.Add(new Customers
{
Id = reader.GetInt32(0),
First_name = reader.GetString(1),
Last_name = reader.GetString(2),
Address = reader.GetString(3),
Zip = reader.GetString(4),
Phone = reader.GetString(5),
Email = reader.GetString(6),
Is_active = reader.GetBoolean(7)
});
}
}
}
return customers;
}
The Status is 404 not found, also the type is html. Maybe you overlook what I did wrong.
CodePudding user response:
I think the problem is the fetch('customers')
part.
It should be fetch('/customers')
(starting with a slash).
Focus on the domain and path, forget the others for now.
fetch('/customers')
When you use a URL starting with a slash/
, it replaces the entire path part from the URL.
So: www.example.com/path/to/myfile -> www.example.com/customersfetch('customers')
When you use a URL that doesn't start with a slash/
, it somehow replaces only the last part of the path (in case it contains multiple parts).
So: www.example.com/path/to/myfile -> www.example.com/path/to/customersYou wouldn't notice this kind of behaviour in case the path contained only 1 part, as the resulting URL would be the same in both cases (either with or without
/
).
Hope it helps.
CodePudding user response:
Have you tried using the forward slash like this?
const response = await fetch('/customers', {
Also, How about adding this in your controller to make your endpoint available:
[Route("customer")]
[ApiController]
public class CustomerController : ControllerBase
{
...
}