First of all here is my code - my controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using DataBase.Data;
using DataBase.Data.Models;
namespace DataBase.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class FoodDatabasesController : ControllerBase
{
private readonly FoodDbContext _context;
public FoodDatabasesController(FoodDbContext context)
{
_context = context;
}
// GET: api/FoodDatabases
[HttpGet]
public async Task<ActionResult<IEnumerable<FoodDatabase>>> GetFoodDatabases()
{
return await _context.FoodDatabases.ToListAsync();
}
// GET: api/FoodDatabases/5
[HttpGet("{id}")]
public async Task<ActionResult<FoodDatabase>> GetFoodDatabase(int id)
{
var foodDatabase = await _context.FoodDatabases.FindAsync(id);
if (foodDatabase == null)
{
return NotFound();
}
return foodDatabase;
}
// PUT: api/FoodDatabases/5
// To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
[HttpPut("{id}")]
public async Task<IActionResult> PutFoodDatabase(int id, FoodDatabase foodDatabase)
{
if (id != foodDatabase.Id)
{
return BadRequest();
}
_context.Entry(foodDatabase).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!FoodDatabaseExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
// POST: api/FoodDatabases
[HttpPost]
public async Task<ActionResult<FoodDatabase>> PostFoodDatabase(FoodDatabase foodDatabase)
{
_context.FoodDatabases.Add(foodDatabase);
await _context.SaveChangesAsync();
return CreatedAtAction("GetFoodDatabase", new { id = foodDatabase.Id }, foodDatabase);
}
// DELETE: api/FoodDatabases/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteFoodDatabase(int id)
{
var foodDatabase = await _context.FoodDatabases.FindAsync(id);
if (foodDatabase == null)
{
return NotFound();
}
_context.FoodDatabases.Remove(foodDatabase);
await _context.SaveChangesAsync();
return NoContent();
}
private bool FoodDatabaseExists(int id)
{
return _context.FoodDatabases.Any(e => e.Id == id);
}
}
}
Here is my database entity and DbContext:
public class FoodDatabase
{
[Key]
public int Id { get; set; }
[MaxLength(150), Column(TypeName = "nvarchar(150)")]
public string Food { get; set; } = "Food Name";
[MaxLength(150), Column(TypeName = "nvarchar(300)")]
public string Description { get; set; } = "Description";
}
public class FoodDbContext : DbContext
{
public FoodDbContext(DbContextOptions<FoodDbContext> options)
: base(options)
{
}
public DbSet<FoodDatabase> FoodDatabases { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Seed data
modelBuilder.Entity<FoodDatabase>().HasData(
new FoodDatabase
{
Id = 1,
Food = "Foodbread",
Description = "A delicious bread made for food lovers"
});
}
}
These are my 2 migrations:
using Microsoft.EntityFrameworkCore.Migrations;
namespace DataBase.Migrations
{
public partial class Initial : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "FoodDatabases",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Food = table.Column<string>(type: "nvarchar(150)", maxLength: 150, nullable: false),
Description = table.Column<string>(type: "nvarchar(300)", maxLength: 150, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_FoodDatabases", x => x.Id);
});
// Seed data
migrationBuilder.InsertData(
table: "FoodDatabases",
columns: new[] { "Id", "Food", "Description" },
values: new object[] { 1, "Foodbread", "A delicious bread made for food lovers" });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "FoodDatabases");
}
}
}
// <auto-generated />
using DataBase.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace DataBase.Migrations
{
[DbContext(typeof(FoodDbContext))]
partial class FoodDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("DataBase.Data.Models.FoodDatabase", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Description")
.IsRequired()
.HasMaxLength(150)
.HasColumnType("nvarchar(300)");
b.Property<string>("Food")
.IsRequired()
.HasMaxLength(150)
.HasColumnType("nvarchar(150)");
b.HasKey("Id");
b.ToTable("FoodDatabases");
});
#pragma warning restore 612, 618
}
}
}
Lastly here is program.cs and the app settings with the connection string:
using DataBase.Data;
using DataBase.Data.Models;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<FoodDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
// Configure CORS
builder.Services.AddCors(options =>
{
options.AddPolicy("CORSPolicy",
builder =>
{
builder
.AllowAnyMethod()
.AllowAnyHeader()
.AllowAnyOrigin();
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseRouting(); // <- This is required for routing
app.UseCors("CORSPolicy"); // Apply CORS policy
app.UseAuthorization();
app.MapControllers();
app.Run();
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Data Source=(localdb)\\MSSQLLocalDB;Database = WebApiReact,Initial Catalog=master;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False"
}
}
The problem I'm currently facing is that when I open the solution in Swagger, and I want to try out the get, post and put functions, they always throws the same error. I'm confused as to why this happens, and looking for some guidance on where I can improve it.
Here is the error I get in Swagger when I try to execute my put function:
Error: response status is 500
Response body
System.Globalization.CultureNotFoundException: Only the invariant culture is supported in globalization-invariant mode. See https://aka.ms/GlobalizationInvariantMode for more information. (Parameter 'name')
en-us is an invalid culture identifier.
at System.Globalization.CultureInfo.GetCultureInfo(String name)
at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource1 retry, SqlConnectionOverrides overrides) at Microsoft.Data.SqlClient.SqlConnection.InternalOpenAsync(CancellationToken cancellationToken) --- End of stack trace from previous location --- at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternalAsync(Boolean errorsExpected, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternalAsync(Boolean errorsExpected, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList1 entriesToSave, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(StateManager stateManager, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at DataBase.Controllers.FoodDatabasesController.PutFoodDatabase(Int32 id, FoodDatabase foodDatabase) in C:\Users\huday\Documents\DataBase\DataBase\Controllers\FoodDatabasesController.cs:line 59at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.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 ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
HEADERS
Accept: */*
Host: localhost:7181
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.5
Content-Type: application/json
Origin: https://localhost:7181
Referer: https://localhost:7181/swagger/index.html
TE: trailers
Content-Length: 60
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-origin
Change your project invariant globalization settins to false. Dotnet using invariant culture by default. If you want to use specific (en-us on your sample) You should do;
Add your csproj file:
Project.csproj
or define environment variable:
Environment Variable
or add env to your docker file:
DockerFile
Also be aware culture string should "en-US" and you can check the other supported culture strings