.NET调用带Basic认证API,EF Core写入SQL Server失败求助
无法写入SQL Server数据库的问题排查与修复
你的代码存在以下几个关键问题,逐一修正后即可正常写入数据:
1. Program.cs 代码结构错误
SaveParties方法被嵌套在FetchParties方法内部,且FetchParties在using块后直接return,导致后续方法定义和调用逻辑永远无法执行。必须将SaveParties移到FetchParties外部。
2. DbContext 核心配置错误
- 混用旧版EF(
System.Data.Entity)和EF Core类型:System.Data.Entity.DbSet<Party>是旧版EF的类型,上下文继承自EF Core的DbContext,应替换为Microsoft.EntityFrameworkCore.DbSet<Party>。 OnConfiguring方法仅定义了连接字符串,但未调用optionsBuilder.UseSqlServer()配置SQL Server提供者,EF Core无法识别目标数据库。- 连接字符串引号嵌套错误:原写法会导致语法错误,需用转义双引号或单引号修正。
- 存在大量无关的
using引用,应清理掉冗余命名空间。
3. 实体类与序列化不匹配
Party类使用XML序列化特性([XmlRoot]、[XmlElement]),但代码用ReadAsAsync<List<Party>>做JSON反序列化,这些XML特性无效。若API返回JSON,需改用JSON序列化特性(如[JsonPropertyName])匹配字段;若返回XML,需配置XML格式化器。- 未显式标记主键:虽EF Core默认识别
Id为主键,但显式添加[Key]特性更稳妥,避免映射歧义。
4. Basic认证凭证错误
- Basic认证需要将
username:password转为Base64编码字符串,原代码直接传入明文组合会导致认证失败,无法获取API数据。
5. 缺少错误处理
- 未对API请求和数据库操作添加异常捕获,无法定位具体错误(如数据库连接失败、主键冲突、字段长度超限等)。
修正后的代码示例
Program.cs
using APItoSQL1.Model; using System.Net.Http.Headers; using System.Text; async Task<List<Party>> FetchParties() { using (var client = new HttpClient()) { // 正确处理Basic认证:将用户名密码转为Base64编码 var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes("username:password")); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials); var response = await client.GetAsync("your-api-url"); response.EnsureSuccessStatusCode(); // 若API返回XML,需添加XML格式化器: // var formatters = new List<MediaTypeFormatter> { new XmlMediaTypeFormatter() }; // var data = await response.Content.ReadAsAsync<List<Party>>(formatters); var data = await response.Content.ReadAsAsync<List<Party>>(); return data; } } async Task SaveParties(List<Party> parties) { try { using (var context = new MyDbContext()) { context.Parties.AddRange(parties); await context.SaveChangesAsync(); } } catch (Exception ex) { // 打印异常信息用于排查 Console.WriteLine($"保存数据失败:{ex.Message}"); throw; // 可选:重新抛出异常让上层处理 } } // 执行调用逻辑 var parties = await FetchParties(); await SaveParties(parties);
MyDbContext.cs
using Microsoft.EntityFrameworkCore; namespace APItoSQL1.Model { public class MyDbContext : DbContext { // 使用EF Core原生DbSet类型 public DbSet<Party> Parties { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { // 修正连接字符串引号,并配置SQL Server提供者 string connectionString = @"Server=""myservername"";Initial Catalog=""myDBname"";Integrated Security=True"; optionsBuilder.UseSqlServer(connectionString); } } }
Party.cs(适配JSON返回的API)
using System.ComponentModel.DataAnnotations; using System.Text.Json.Serialization; namespace APItoSQL1.Model { public class Party { [Key] // 显式标记主键 [JsonPropertyName("id")] // 与API返回的JSON字段名对应 public int Id { get; set; } [JsonPropertyName("isOrganization")] public bool IsOrganization { get; set; } [JsonPropertyName("primeName")] public string PrimeName { get; set; } [JsonPropertyName("email")] public string Email { get; set; } [JsonPropertyName("givenName")] public string GivenName { get; set; } [JsonPropertyName("phone")] public string Phone { get; set; } } }
内容的提问来源于stack exchange,提问作者Daniela Gómez
相关产品推荐
相关产品推荐

