HTTP 请求错误:InternalServerError 内部服务器错误:An 保存实体更改时发生错误。看内在 详细信息例外。
我在尝试从 Xamarin android 表单保存到数据库时遇到此错误 启动.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using PFAG1_2Cars.Core.Repositories;
using PFAG1_2Cars.Core.Services;
using PFAG1_2Cars.Core;
using PFAG1_2Cars.Data;
using PFAG1_2Cars.Data.Repositories;
using PFAG1_2Cars.Data.UnitOfWork;
using PFAG1_2Cars.Services.Services;
namespace Web.API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
// Configure DbContext
services.AddDbContext<PFAG1_2CarsDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
// Register repositories
services.AddScoped<IUnitOfWork, UnitOfWork>();
services.AddScoped<IAssuranceRepository, AssuranceRepository>();
services.AddScoped<IRoleRepository, RoleRepository>();
services.AddScoped<ICategorieRepository, CategorieRepository>();
services.AddScoped<ICompanyAssuranceRepository, CompanyAssuranceRepository>();
services.AddScoped<ICompteRepository, CompteRepository>();
services.AddScoped<IControleTechniqueRepository, ControleTechniqueRepository>();
services.AddScoped<IInterventionRepository, InterventionRepository>();
services.AddScoped<IMarqueRepository, MarqueRepository>();
services.AddScoped<IModelRepository, ModelRepository>();
services.AddScoped<IPrestationRepository, PrestationRepository>();
services.AddScoped<ICarRepository, CarRepository>();
// Register services
services.AddScoped<IAssuranceService, AssuranceService>();
services.AddScoped<IRoleService, RoleService>();
services.AddScoped<ICategorieService, CategoryService>();
services.AddScoped<ICompanyAssuranceService, CompanyAssuranceService>();
services.AddScoped<ICompteService, CompteService>();
services.AddScoped<IControleTechniqueService, ControleTechniqueService>();
services.AddScoped<IInterventionService, InterventionService>();
services.AddScoped<IMarqueService, MarqueService>();
services.AddScoped<IModelService, ModelService>();
services.AddScoped<IPrestationService, PrestationService>();
services.AddScoped<ICarService, CarService>();
services.AddControllers();
services.AddLogging();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
程序.cs:
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace Web.API
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole(); // Output to console
logging.AddDebug(); // Output to debug window
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.UseUrls("http://192.168.x.x:5050");
});
}
}
appsettings.json:
{
"ConnectionStrings": {
"DefaultConnection": "Server=192.168.x.x\\SQLEXPRESS,1433;Database=xxx;User Id=xxx;Password=xxx;Encrypt=False;"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ApiBaseUrl": "https://192.168.x.x:5050/api/"
}
您的控制器:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using PFAG1_2Cars.Core.Entities;
using PFAG1_2Cars.Core.Services;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Web.API.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class YourController : ControllerBase
{
private readonly IMarqueService _marqueService;
private readonly ILogger<YourController> _logger;
public YourController(IMarqueService marqueService, ILogger<YourController> logger)
{
_marqueService = marqueService;
_logger = logger;
}
// GET: api/your
[HttpGet]
public async Task<ActionResult<IEnumerable<Marque>>> GetMarques()
{
try
{
_logger.LogInformation("Getting all marques");
var marques = await _marqueService.GetAllMarques();
return Ok(marques);
}
catch (Exception ex)
{
_logger.LogError(ex, "An error occurred while getting marques.");
return StatusCode(500, $"Internal server error: {ex.Message}");
}
}
// GET: api/your/5
[HttpGet("{id}")]
public async Task<ActionResult<Marque>> GetMarque(int id)
{
try
{
_logger.LogInformation($"Getting marque with ID {id}");
var marque = await _marqueService.GetMarqueById(id);
if (marque == null)
{
_logger.LogWarning($"Marque with ID {id} not found.");
return NotFound();
}
return Ok(marque);
}
catch (Exception ex)
{
_logger.LogError(ex, $"An error occurred while getting marque with ID {id}.");
return StatusCode(500, $"Internal server error: {ex.Message}");
}
}
// POST: api/your
[HttpPost]
public async Task<ActionResult<Marque>> PostMarque(Marque marque)
{
try
{
_logger.LogInformation("Creating a new marque");
var newMarque = await _marqueService.CreateMarque(marque);
return CreatedAtAction(nameof(GetMarque), new { id = newMarque.IdMarque }, newMarque);
}
catch (Exception ex)
{
_logger.LogError(ex, "An error occurred while creating a new marque.");
return StatusCode(500, $"Internal server error: {ex.Message}");
}
}
// PUT: api/your/5
[HttpPut("{id}")]
public async Task<IActionResult> PutMarque(int id, Marque marque)
{
try
{
_logger.LogInformation($"Updating marque with ID {id}");
await _marqueService.UpdateMarque(new Marque { IdMarque = id }, marque);
return NoContent();
}
catch (Exception ex)
{
_logger.LogError(ex, $"An error occurred while updating marque with ID {id}.");
return StatusCode(500, $"Internal server error: {ex.Message}");
}
}
// DELETE: api/your/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteMarque(int id)
{
try
{
_logger.LogInformation($"Deleting marque with ID {id}");
await _marqueService.DeleteMarqueById(id);
return NoContent();
}
catch (Exception ex)
{
_logger.LogError(ex, $"An error occurred while deleting marque with ID {id}.");
return StatusCode(500, $"Internal server error: {ex.Message}");
}
}
}
}
MarqueForm.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TEST.MarqueForm">
<ContentPage.Content>
<StackLayout Padding="20">
<Entry x:Name="IdMarqueEntry" Placeholder="Enter Id Marque" Keyboard="Numeric" />
<Entry x:Name="NomMarqueEntry" Placeholder="Enter Nom Marque" />
<Button Text="Submit" Clicked="OnSubmitClicked" />
<Label x:Name="ResultLabel" Text="Result will be displayed here" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
MarqueForm.xaml.cs:
using Newtonsoft.Json;
using PFAG1_2Cars.Core.Entities;
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace TEST
{
public partial class MarqueForm : ContentPage
{
private readonly HttpClient _httpClient;
public MarqueForm()
{
InitializeComponent();
_httpClient = new HttpClient();
_httpClient.BaseAddress = new Uri("http://192.168.1.100:5050/api/your"); // Adjust base URL as needed
}
private async void OnSubmitClicked(object sender, EventArgs e)
{
try
{
if (!int.TryParse(IdMarqueEntry.Text, out int idMarque))
{
ResultLabel.Text = "Invalid Id Marque. Please enter a valid integer.";
return;
}
var marque = new Marque
{
IdMarque = idMarque,
NomMarque = NomMarqueEntry.Text
};
await PostMarqueAsync(marque);
}
catch (Exception ex)
{
ResultLabel.Text = $"Exception: {ex.Message}";
Console.WriteLine($"Exception: {ex.Message}");
}
}
private async Task PostMarqueAsync(Marque marque)
{
try
{
var json = JsonConvert.SerializeObject(marque);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync("", content); // Adjust endpoint if necessary
if (response.IsSuccessStatusCode)
{
ResultLabel.Text = "Marque added successfully!";
}
else
{
var responseContent = await response.Content.ReadAsStringAsync();
ResultLabel.Text = $"Error: {response.StatusCode}\n{responseContent}";
// Log the error to the console
Console.WriteLine($"HTTP Request Error: {response.StatusCode}\n{responseContent}");
}
}
catch (Exception ex)
{
ResultLabel.Text = $"Exception: {ex.Message}";
Console.WriteLine($"Exception: {ex.Message}");
}
}
}
}
我尝试了使用以下网址的 post 方法:http://192.168.x.x:5050/api/your 在Postman、电脑浏览器和手机浏览器中
EF 喜欢将异常隐藏在 InnerException 中,因此错误详细信息实际上在那里,但你的日志不会输出它。在处理这种异常情况时,您可以考虑:
对于方法 2,这是我用来处理中间件中的异常日志记录的小工具,
public static string GetActualMessage(this Exception e)
{
if (e.InnerException == null)
return e.Message;
HashSet<Exception> traversed = new();
Exception current = e;
while (traversed.Add(current) && current.InnerException != null)
{
current = current.InnerException;
}
return current.Message;
}
使用它来获取实际消息可能是这样的,
try {
// ...
} catch (Exception e) {
Console.WriteLine(e.GetActualMessage());
}