C# InsertCustomerRecord方法不应抛异常时出现空引用异常问题
空引用异常排查及修复方案
异常触发原因
你遇到的未捕获空引用异常核心由三个问题导致:
- try块覆盖范围不全:你写的
model.PhoneNumber解析、model.USPSAddressValidated强转逻辑都在try块之外,这部分代码触发的异常不会被catch捕获。如果入参model本身为null,或者model.USPSAddressValidated是无值的可空类型,都会直接抛出空引用/转换异常,这也是你明明加了异常捕获还是会抛异常的核心原因。 - 字符串操作逻辑顺序错误:所有形如
model.AddressLine1.ToUpper() ?? ""的代码逻辑完全颠倒,空合并运算符??只有在前面的表达式返回null时才会生效,但如果AddressLine1本身为null,调用ToUpper()的动作会先触发空引用异常,??根本不会执行。同理FirstName、LastName、City等所有直接调用ToUpper()的字符串属性,只要为null就会触发异常。 - 可空值类型未判空:如果
model.DateOfBirth是可空日期类型(DateTime?),无值时直接调用ToShortDateString()也会触发空引用异常。
修复方案
- 调整try块覆盖范围:将入参处理逻辑全部移入try块,或者在方法入口先对
model做非空校验。 - 修正字符串操作顺序:所有字符串转大写前先判空,把
x.ToUpper() ?? ""统一改为(x ?? "").ToUpper(),先处理空值再调用方法。 - 可空值类型判空:对
DateOfBirth这类可空值类型先判断是否有值,无值时传入DBNull.Value或者默认值。 - 增加可空枚举校验:如果
model.USPSAddressValidated是可空枚举,强转前先判断是否有值,避免转换异常。
修正后代码示例
private async Task<long> InsertCustomerRecord(CreateCustomerModel model) { // 提前做入参非空校验 if (model == null) { Console.WriteLine("入参model为空"); return 0; } try { Int64 phoneNumber = 0; var isParsed = Int64.TryParse(model.PhoneNumber, out phoneNumber); if (!isParsed) phoneNumber = 0; // 可空枚举校验,根据实际类型调整默认值 var USPSAddressValidatedId = model.USPSAddressValidated is null ? 0 : (int)model.USPSAddressValidated; IDataParameter[] parameters = new IDataParameter[] { new SqlParameter("@FirstName", (model.FirstName ?? "").ToUpper()), new SqlParameter("@LastName", (model.LastName ?? "").ToUpper()), new SqlParameter("@AddressLine1",(model.AddressLine1 ?? "").ToUpper()), new SqlParameter("@AddressLine2",(model.AddressLine2 ?? "").ToUpper()), new SqlParameter("@City",(model.City ?? "").ToUpper()), new SqlParameter("@State",(model.State ?? "").ToUpper()), new SqlParameter("@CountyCode",(model.CountyCode ?? "").ToUpper()), new SqlParameter("@ZipCode",model.ZipCode), // 可空日期处理,根据实际需求调整默认值 new SqlParameter("@DateOfBirth", model.DateOfBirth.HasValue ? model.DateOfBirth.Value.ToShortDateString() : DBNull.Value), new SqlParameter("@Phone",phoneNumber), new SqlParameter("@Email",(model.EmailAddress ?? "").ToUpper()), new SqlParameter("@PersonalRepresentative",(model.CustomerClass ?? "").ToUpper()), new SqlParameter("@ExpiryDate", model.ExpirationDate), new SqlParameter("@CustomerClass", model.Customer_Class), new SqlParameter("@USPSAddressValidated",USPSAddressValidatedId ), new SqlParameter("@ImportFromLegacySystem", model.ImportFromLegacySystem) }; return await InsertUpdateProcedure("RF_InsertCustomerCard", parameters); } catch (Exception e) { Console.WriteLine(e.Message); return 0; } }
内容的提问来源于stack exchange,提问作者GettingStarted
相关产品推荐
相关产品推荐

