You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core Web API路径逗号分隔decimal数组解析异常原因及解决方案

问题原因
  • .NET Core 2.1的路由参数模型绑定仅对string[]、int[]、Guid[]等少数常用数组类型,内置了逗号拆分的自动解析逻辑,decimal[]不在默认支持自动拆分的类型列表中。
  • 当模型绑定器未对decimal[]触发逗号拆分逻辑时,会将整个逗号分隔的路径字符串作为单个值传入decimal类型转换器。默认的decimal转换器会将字符串中的逗号识别为千位分隔符直接忽略,最终拼接为一个完整的十进制数值,因此你得到的数组仅包含一个拼接后的大数值。
解决方案

你可以通过自定义路由参数模型绑定器实现逗号分隔decimal数组的正确解析,无需修改现有传参规范,步骤如下:

1. 实现自定义模型绑定器

using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.Globalization;

public class DecimalArrayRouteBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        // 仅处理decimal[]类型的参数
        if (bindingContext.ModelType != typeof(decimal[]))
        {
            return Task.CompletedTask;
        }
        
        // 从路由中获取原始参数字符串
        var routeValue = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).FirstValue;
        if (string.IsNullOrWhiteSpace(routeValue))
        {
            bindingContext.Result = ModelBindingResult.Success(Array.Empty<decimal>());
            return Task.CompletedTask;
        }
        
        // 按逗号拆分字符串并逐个转换为decimal
        var splitValues = routeValue.Split(',', StringSplitOptions.RemoveEmptyEntries);
        var resultList = new List<decimal>();
        foreach (var val in splitValues)
        {
            if (decimal.TryParse(val, NumberStyles.Number, CultureInfo.InvariantCulture, out var decimalVal))
            {
                resultList.Add(decimalVal);
            }
            else
            {
                bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, $"无效的decimal值:{val}");
                return Task.CompletedTask;
            }
        }
        
        bindingContext.Result = ModelBindingResult.Success(resultList.ToArray());
        return Task.CompletedTask;
    }
}

2. 应用绑定器

单参数应用

如果仅当前接口需要使用,直接在Action的参数上添加绑定器特性即可:

[HttpGet("details/{shipmentDetailIds}")]
public async Task<List<ShipmentDetail>> GetByShipmentDetailIds(
    [ModelBinder(typeof(DecimalArrayRouteBinder))] decimal[] shipmentDetailIds)
{
    // 原有业务逻辑保持不变
}

全局应用

如果项目中多处需要用到路径传参的decimal数组解析,可以在Startup中全局注册绑定器,避免每个参数重复加特性:

// Startup.cs的ConfigureServices方法中添加配置
services.AddMvc(options =>
{
    // 优先使用自定义的decimal数组绑定器
    options.ModelBinders.Insert(0, new DecimalArrayRouteBinder());
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

注意事项

示例中使用CultureInfo.InvariantCulture(固定文化)解析decimal,避免不同服务器的区域配置导致小数点、千位分隔符识别混乱。如果你的业务需要适配特定区域的数字格式,直接修改decimal.TryParse的文化参数即可。


内容的提问来源于stack exchange,提问作者Simon Elms

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 05:45:03