C#10中如何为模型内嵌套对象设置默认值 解决ASP.NET Core Web API空引用报错
ASP.NET Core Web API 模型空引用报错解决方案
报错原因
你收到的报错翻译为:System.NullReferenceException: 未将对象引用设置到对象的实例。 位于 TechnePaymentApi.Controllers.PublicApi.PublicOpayoPaymentController.Payment(PaymentViewModel payment
触发异常的根本原因是两层引用类型属性未初始化:
- 前端请求显式传递了
PaymentMethod: null,模型反序列化后PaymentRequestViewModel.PaymentMethod属性为null - 即使
PaymentMethod不为null,你的PaymentMethodViewModel类中Card属性也未设置默认实例,同样可能为null
直接访问null对象的子属性就会抛出空引用异常。
解决方案
可根据业务需求选择以下两种实现方式:
方案1:模型层设置默认实例(推荐)
直接在模型定义时为引用类型属性初始化默认实例,适合该属性绝大多数场景下都需要非空的场景:
修改PaymentRequestViewModel:
public class PaymentRequestViewModel { // 初始化PaymentMethod默认实例 public PaymentMethodViewModel PaymentMethod { get; set; } = new PaymentMethodViewModel(); public string TransactionType { get; set; } //其余代码已省略 }
修改PaymentMethodViewModel:
public class PaymentMethodViewModel { // 初始化Card默认实例 public CardViewModel Card { get; set; } = new CardViewModel(); }
注意:如果需要避免前端传递的null值覆盖默认实例,可在Program.cs中配置反序列化忽略null值:
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull; });
方案2:控制器层赋值前做null校验
适合仅在当前接口需要非空、其他场景允许属性为null的场景,修改控制器代码:
public async Task<IActionResult> Payment([FromBody] PaymentViewModel paymentViewModel) { // 层级校验属性是否为null,为空则初始化 if (paymentViewModel.PaymentRequest.PaymentMethod == null) { paymentViewModel.PaymentRequest.PaymentMethod = new PaymentMethodViewModel(); } if (paymentViewModel.PaymentRequest.PaymentMethod.Card == null) { paymentViewModel.PaymentRequest.PaymentMethod.Card = new CardViewModel(); } paymentViewModel.PaymentRequest.PaymentMethod.Card.Reusable = true; //其余代码已省略 }
内容的提问来源于stack exchange,提问作者hanushic
相关产品推荐
相关产品推荐

