ASP.NET Core Web API中TryGetValue空键参数异常问题
问题:Dictionary.TryGetValue抛出「Value cannot be null. (Parameter 'key')」异常
开发ASP.NET Core Web API后端,调用外部API获取数据后,在AssignName()方法中调用Dictionary.TryGetValue时触发异常,错误信息为「Value cannot be null. (Parameter 'key')」。经排查,异常是由于传入TryGetValue的key(delivery.StatusId或delivery.CustomerId)为null导致。
相关代码
public async Task<IPagedList<TblDeliveryModel>> Handle(GetListTblDeliveryQuery request, CancellationToken cancellationToken) { if (request == null) { throw new BaseException("Bạn chưa nhập dữ liệu gì"); } var query = from p in _repository.Table<TblDelivery>() select p; // API Customer var uriCustomer = _configuration["Api:Pos"]+ "/api/v1/TblDmCustomer/get-customer-by-list-id?ids=201777&ids=201778&ids=201779&ids=201780"; MessageResponse response = await _callApiService.CallAPIAsync<MessageResponse>(uri: uriCustomer, bearerToken: _authorizeExtension.AcessToken); List<DeliveryCustomerModel> listCutomers = response.data.ToObject<List<DeliveryCustomerModel>>(); if (!string.IsNullOrEmpty(request.KeySearch)) // KeySearch Có ký tự nhập vào thì { if (long.TryParse(request.KeySearch, out var _IdCus)) { query = from p in _repository.Table<TblDelivery>() where p.OrderHeaderId == _IdCus select p; } else { throw new BaseException("KeySearch tìm kiếm theo OrderHeaderId, không được nhập chuỗi ký tự"); } } // Call API var uri = Url.Mdm_Url + "TblDmDeliveryStatus/get-all"; MessageResponse responseStatus = await _callApiService.CallAPIAsync<MessageResponse>(uri: uri, bearerToken: _authorizeExtension.AcessToken); List<DeliveryStatusModel> listDeliveryStatusModel = responseStatus.data.ToObject<List<DeliveryStatusModel>>(); // order var orderDelivery = query.OrderByDescending(c => c.CreateDate); if (!string.IsNullOrEmpty(request.Sort)) { var fieldType = request.Sort.GetPropertyGetter<TblDelivery>(); orderDelivery = request.IsOrder == true ? query.OrderBy(fieldType) : query.OrderByDescending(fieldType); } // Take and skip danh sách var pageList = await orderDelivery.PagedList(request.Take, request.Skip); PagedList<TblDeliveryModel> res = new PagedList<TblDeliveryModel>(); res.Lists = _mapper.Map<List<TblDeliveryModel>>(pageList.Lists); res.Count = pageList.Count; AssignName(res, listDeliveryStatusModel,listCutomers); if (!res.Lists.AnyList()) { throw new BaseException("Không có dữ liệu"); } return res; } public void AssignName(PagedList<TblDeliveryModel> tblDelvieryModel, List<DeliveryStatusModel> listDeliveryStatusModel, List<DeliveryCustomerModel> listDeliveryCustomer) { var statusDictionary = listDeliveryStatusModel.ToDictionary(x => x.Id, x => x.Name); var customerDictionary = listDeliveryCustomer.ToDictionary(x => x.Id, x => x.Name); foreach (var delivery in tblDelvieryModel.Lists) { if (statusDictionary.TryGetValue(delivery.StatusId, out var statusName)) { delivery.Status = statusName; } if (customerDictionary.TryGetValue(delivery.CustomerId, out var nameCustomer)) { delivery.NameCustomer = nameCustomer; } } }
异常信息
[External Code] Api.App.Application.Query.Handler.Delivery.GetListTblDeliveryQueryHandler.AssignName(Hacom.Core.Infrastructure.PagedList<Api.App.Application.Query.Model.Delivery.TblDeliveryModel>, System.Collections.Generic.List<Api.App.Application.Query.Handler.Delivery.Model.DeliveryStatusModel>, System.Collections.Generic.List<Api.App.Application.Query.Handler.Delivery.Model.DeliveryCustomerModel>) in GetListTblDeliveryQuery.cs Message: Value cannot be null. (Parameter 'key') StackTrace: at System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument) at System.Collections.Generic.Dictionary`2.FindValue(TKey key) at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value) at Api.App.Application.Query.Handler.Delivery.GetListTblDeliveryQueryHandler.AssignName(PagedList`1 tblDelvieryModel, List`1 listDeliveryStatusModel, List`1 listDeliveryCustomer) in D:\USB_MSI\Intern_Hacom\BuildProject_Pos\_hacom\hacom\project\api\hacom.api.delivery-and-testing\Api.App\Application\Query\Handler\Delivery\GetListTblDeliveryQuery.cs:line 108
解决方案
方案1:调用TryGetValue前先检查key是否为null
修改AssignName方法,在调用TryGetValue前先判断key是否为null,避免传入空值:
public void AssignName(PagedList<TblDeliveryModel> tblDelvieryModel, List<DeliveryStatusModel> listDeliveryStatusModel, List<DeliveryCustomerModel> listDeliveryCustomer) { var statusDictionary = listDeliveryStatusModel.ToDictionary(x => x.Id, x => x.Name); var customerDictionary = listDeliveryCustomer.ToDictionary(x => x.Id, x => x.Name); foreach (var delivery in tblDelvieryModel.Lists) { // 检查StatusId不为null再执行查找 if (delivery.StatusId != null && statusDictionary.TryGetValue(delivery.StatusId.Value, out var statusName)) { delivery.Status = statusName; } // 检查CustomerId不为null再执行查找 if (delivery.CustomerId != null && customerDictionary.TryGetValue(delivery.CustomerId.Value, out var nameCustomer)) { delivery.NameCustomer = nameCustomer; } } }
方案2:使用GetValueOrDefault方法(.NET Core 2.0+)
Dictionary<TKey, TValue>.GetValueOrDefault允许传入null key且不会抛出异常,若key不存在或为null则返回类型默认值:
public void AssignName(PagedList<TblDeliveryModel> tblDelvieryModel, List<DeliveryStatusModel> listDeliveryStatusModel, List<DeliveryCustomerModel> listDeliveryCustomer) { var statusDictionary = listDeliveryStatusModel.ToDictionary(x => x.Id, x => x.Name); var customerDictionary = listDeliveryCustomer.ToDictionary(x => x.Id, x => x.Name); foreach (var delivery in tblDelvieryModel.Lists) { delivery.Status = statusDictionary.GetValueOrDefault(delivery.StatusId); delivery.NameCustomer = customerDictionary.GetValueOrDefault(delivery.CustomerId); } }
额外建议
- 从数据库查询
TblDelivery时,若允许StatusId或CustomerId为null,需在业务逻辑中明确空值处理规则 - 外部API返回的字典源数据,需提前校验
x.Id是否为null(ToDictionary会在源数据key为null时直接抛出异常)
内容的提问来源于stack exchange,提问作者Thanh DevS
相关产品推荐
相关产品推荐

