HTTP 请求错误:InternalServerError 内部服务器错误:保存实体更改时发生错误

问题描述 投票:0回答:1

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、电脑浏览器和手机浏览器中

c# xamarin xamarin.forms xamarin.android
1个回答
0
投票

EF 喜欢将异常隐藏在 InnerException 中,因此错误详细信息实际上在那里,但你的日志不会输出它。在处理这种异常情况时,您可以考虑:

  1. 使用调试器和断点查看运行时异常详细信息。
  2. 确保您收到包含实际消息的 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());
}
© www.soinside.com 2019 - 2024. All rights reserved.