ASP.NET 4.8升级至ASP.NET Core 6.0遇NullReferenceException问题
ASP.NET 4.8升级到ASP.NET Core 6.0后OData接口空引用异常问题
将项目从ASP.NET 4.8升级到ASP.NET Core 6.0后,原有代码在ASP.NET环境运行正常,但访问资源地址http://localhost/odata/Users时触发System.NullReferenceException错误,调试器指向var lsret = new List<User>();行,尝试多种方法未解决。
相关代码
UserService.cs
namespace pal_data.Business { public class UserService { public List<User> GetData() { try { var lsret = new List<User>(); // 错误提示:System.NullReferenceException: 对象引用未设置到对象的实例。 using (SqlConnection con = new(System.Configuration.ConfigurationManager.ConnectionStrings["MyConnPort"].ConnectionString)) { var strSQL = "select a.*, b.RoleName from AppUser a inner join AccessRole b on a.RoleID = b.AccessRoleID"; using (SqlDataAdapter da = new(strSQL, con)) { var dt = new DataTable(); da.Fill(dt); foreach (DataRow dr in dt.Rows) { var item = new User { UserID = int.Parse(dr["AppUserID"].ToString() ?? ""), RoleID = int.Parse(dr["RoleID"].ToString() ?? ""), Role = dr["RoleName"].ToString() ?? "", UserName = dr["UserName"].ToString() ?? "", Name = dr["Name"].ToString() ?? "", Password = dr["Password"].ToString() }; lsret.Add(item); } } } return lsret; } catch (SqlException ex) { // ... } catch (Exception e) { // ... } } } }
UsersController.cs
namespace pal_data.Controllers { [EnableCors] public class UsersController : ODataController { private readonly UserService m_service = new(); [EnableQuery] public ActionResult<IEnumerable<User>> Get() { return Ok(m_service.GetData()); } } }
User.cs
namespace pal_data.Models { public class User { public int UserID { get; set; } public string? FunctionResult { get; set; } public int ReturnCode { get; set; } public int RoleID { get; set; } public string? Role { get; set; } public string? UserName { get; set; } public string? Name { get; set; } public string? Password { get; set; } } }
可正常运行的UserService版本
- 此版本无空引用错误,可正常返回数据
namespace pal_data.Business { public class UserService { public List<User> GetData() { var lsret = new List<User> { new User { UserID = 1, RoleID = 1, Role = "asdfsdf", UserName = "sadfsdf", Name = "sdfasdf", Password = "asdfsdf", } }; return lsret; } } }
问题分析
错误提示指向new List<User>()是误导,实际异常根源是:
- ASP.NET Core中不再使用
System.Configuration.ConfigurationManager读取配置,ConnectionStrings["MyConnPort"]会返回null,访问其ConnectionString属性时抛出空引用异常。 - catch块未做有效处理,既没有返回默认列表也没有重新抛出异常,导致方法最终返回null,上层调用
Ok(m_service.GetData())时触发空引用。
解决方案
1. 替换配置读取方式为ASP.NET Core原生注入
在UserService中通过构造函数注入IConfiguration,替代ConfigurationManager:
namespace pal_data.Business { public class UserService { private readonly IConfiguration _configuration; public UserService(IConfiguration configuration) { _configuration = configuration; } public List<User> GetData() { var lsret = new List<User>(); try { string connStr = _configuration.GetConnectionString("MyConnPort") ?? throw new InvalidOperationException("未找到连接字符串MyConnPort"); using (SqlConnection con = new(connStr)) { var strSQL = "select a.*, b.RoleName from AppUser a inner join AccessRole b on a.RoleID = b.AccessRoleID"; using (SqlDataAdapter da = new(strSQL, con)) { var dt = new DataTable(); da.Fill(dt); foreach (DataRow dr in dt.Rows) { var item = new User { UserID = int.Parse(dr["AppUserID"].ToString() ?? ""), RoleID = int.Parse(dr["RoleID"].ToString() ?? ""), Role = dr["RoleName"].ToString() ?? "", UserName = dr["UserName"].ToString() ?? "", Name = dr["Name"].ToString() ?? "", Password = dr["Password"].ToString() }; lsret.Add(item); } } } } catch (SqlException ex) { // 添加错误日志记录 } catch (Exception e) { // 添加错误日志记录 } return lsret; } } }
2. 修改控制器,通过构造函数注入UserService
ASP.NET Core推荐依赖注入,避免直接实例化服务:
namespace pal_data.Controllers { [EnableCors] public class UsersController : ODataController { private readonly UserService _service; public UsersController(UserService service) { _service = service; } [EnableQuery] public ActionResult<IEnumerable<User>> Get() { return Ok(_service.GetData()); } } }
3. 在Program.cs中注册服务
var builder = WebApplication.CreateBuilder(args); // 添加控制器和OData服务 builder.Services.AddControllers().AddOData(options => { options.Select().Filter().OrderBy(); options.AddRouteComponents("odata", GetEdmModel()); }); // 注册UserService为依赖注入服务 builder.Services.AddScoped<UserService>(); var app = builder.Build(); // 中间件配置(如CORS、路由等) app.UseCors(); app.UseRouting(); app.MapControllers(); app.Run(); // 构建EDM模型示例 private static IEdmModel GetEdmModel() { ODataConventionModelBuilder builder = new(); builder.EntitySet<User>("Users"); return builder.GetEdmModel(); }
4. 确保appsettings.json中有正确的连接字符串
{ "ConnectionStrings": { "MyConnPort": "你的数据库连接字符串" } }
内容的提问来源于stack exchange,提问作者xinthose
相关产品推荐
相关产品推荐

