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

自定义模型绑定器问题:表单数组动态字段绑定至对应索引

自定义模型绑定器:动态字段绑定到对应数组索引问题

我需要实现一个自定义模型绑定器,将表单中的动态字段(任意名称,支持文件)绑定到OrderItems数组对应索引的ProductInputFieldValue[]集合中,但目前遇到了无法按索引区分处理表单数据的问题。

视图模型定义

public class NewOrderViewModel
{
    public Guid DeliveryAddressId { get; set; }
    public Guid BillingAddressId { get; set; }
    public OrderItemViewModel[] OrderItems { get; set; }
}

public class OrderItemViewModel
{
    public Guid ProductId { get; set; }
    public int Quantity { get; set; }
    public ProductInputFieldValue[] ProductInputFieldValues { get; set; }   
}

POST表单请求数据

DeliveryAddressId:44fbc2e3-07eb-47bc-810c-21dbc8d6924c
BillingAddressId:44fbc2e3-07eb-47bc-810c-21dbc8d6924c
OrderItems[0].ProductId:5124b7f1-8845-4c85-bacf-167dc53f187a
OrderItems[0].Quantity:1
OrderItems[0].file-to-read:44fbc2e3-07eb-47bc-810c-21dbc8d6924c
OrderItems[1].ProductId:5124b7f1-8845-4c85-bacf-167dc53f187a
OrderItems[1].Quantity:1
OrderItems[1].file-to-read:44fbc2e3-07eb-47bc-810c-21dbc8d6924c

其中file-to-read是动态字段示例,这类字段名称不固定,我需要把所有视图模型中未定义的字段(包括文件)都绑定到对应OrderItems索引的ProductInputFieldValues数组里。

尝试的模型绑定器实现

public class ProductInputFieldValueModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException(nameof(bindingContext));
        }

        // BindingSource 总是为null,暂不处理
        if (bindingContext.BindingSource != BindingSource.Custom)
        {
            return Task.CompletedTask;
        }

        var inputFieldValues = new List<ProductInputFieldValue>();

        if (bindingContext.HttpContext.Request.Form.Files.Count > 0)
        {
            var fileInputValues = BindFileInputs(bindingContext.HttpContext.Request.Form.Files);
            inputFieldValues.AddRange(fileInputValues);
        }

        foreach (var key in bindingContext.HttpContext.Request.Form.Keys)
        {
            // 跳过已存在的模型字段
            if (bindingContext.ModelState.ContainsKey(key))
            {
                continue;
            }

            var valueProviderResult = bindingContext.ValueProvider.GetValue(key);
            bindingContext.ModelState.SetModelValue(key, valueProviderResult);
            inputFieldValues.AddRange(valueProviderResult.Values.Select(value =>
                new ProductInputFieldValue
                {
                    Name = key,
                    Value = value
                }));
        }

        bindingContext.Result = ModelBindingResult.Success(inputFieldValues);
        return Task.CompletedTask;
    }
}

绑定器提供者配置

public class ProductInputFieldValuesBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(ModelBinderProviderContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        if (context.Metadata.ModelType == typeof(List<ProductInputFieldValue>))
        {
            return new BinderTypeModelBinder(typeof(ProductInputFieldValueModelBinder));
        }

        return null;
    }
}

核心问题

当前bindingContext.HttpContext.Request.Form返回的是整个表单的所有数据,我无法区分当前正在绑定的是OrderItems数组的哪个索引,也就无法将动态字段分配到对应的ProductInputFieldValues集合中。

想请教:这个需求是否可行?如果可行该如何调整实现?或者有没有其他替代方案?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 23:04:53