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

ASP.NET Core中DevExtreme DataGrid与表单一同提交的问题

问题描述

在ASP.NET Core Razor页面项目中使用DevExtreme DataGrid控件实现添加带手机号的联系人功能:表单头部收集姓名、出生日期等基础信息,DataGrid负责手机号的增删改操作。配置DataGrid的远程数据源URL后,提交表单时出现ViewModel绑定异常,无法获取表单头部的基础数据,同时也无法将DataGrid中的手机号数据与表单一同提交。

解决方案

核心问题分析

当前使用RemoteController作为DataGrid数据源时,DataGrid的增删改操作通过独立AJAX请求触发服务器端Action,这些Action仅修改服务器端内存中的ViewModel数据,但客户端表单并未同步这些变更;同时PartyViewModel中的PhoneNumbers是只读属性(仅get),导致模型绑定无法填充数据,最终提交时ViewModel的基础数据和手机号数据都无法正确获取。

具体修改步骤

  1. 调整ViewModel的可绑定性
    修改PartyViewModel中的PhoneNumbers属性,添加setter以支持模型绑定:
public class PartyViewModel
{
    public Guid Id { get; set; } = Guid.Empty;
    public string FirstName { get; set; } = string.Empty;
    public string LastName { get; set; } = string.Empty;
    [DataType(DataType.Date)]
    public DateTime? Birthdate { get; set; }
    public PartyType Type { get; set; } = PartyType.Unknown;
    // 将只读属性改为可读写,支持模型绑定
    public List<PartyPhoneViewModel> PhoneNumbers { get; set; } = new();
}
  1. 切换DataGrid为客户端数据源模式
    移除RemoteController配置,改用客户端数组数据源直接绑定到ViewModel的PhoneNumbers,开启双向绑定确保客户端修改同步到表单字段:
<div class="col-12 mb-3">
    @(
        Html.DevExtreme().DataGrid<PartyPhoneViewModel>()
            .ShowBorders(true)
            .ID("grdPartyPhones")
            .ColumnAutoWidth(true)
            .RepaintChangesOnly(true)
            .AllowColumnResizing(true)
            .TwoWayBindingEnabled(true)
            .ColumnResizingMode(ColumnResizingMode.NextColumn)
            // 使用客户端数组数据源,直接绑定ViewModel的PhoneNumbers
            .DataSource(m => m.Array().Data(Model.ViewModel.PhoneNumbers))
            .Columns(column =>
            {
                column.AddFor(x => x.PhoneNumber);
                column.AddFor(x => x.Type).Lookup(lookup => lookup
                    .DataSource(Html.GetEnumSelectList<PartyPhoneTypeEnum>()
                    .Select(i => new { Value = int.Parse(i.Value), Text = i.Text }))
                    .ValueExpr("Value")
                    .DisplayExpr("Text"));
            })
            .Editing(edit => edit
                .RefreshMode(GridEditRefreshMode.Full)
                .AllowAdding(true)
                .AllowDeleting(true)
                .AllowUpdating(true)
                .UseIcons(true)
            )
    )
</div>
  1. 移除不必要的服务器端Grid操作
    删除PageModel中所有与Grid远程操作相关的代码(Grid Actions和Grid Row Methods区域),客户端模式下不需要这些独立AJAX接口,DataGrid的修改会直接同步到表单隐藏字段,提交时一并提交。

  2. 简化PageModel逻辑
    修改后的PageModel仅保留核心页面生命周期和提交逻辑:

public class PartyPageModel : NGBasePageModel
{
    [BindProperty]
    public PartyViewModel ViewModel { get; set; } = new();

    public PartyPageModel(IServiceProvider serviceProvider) : base(serviceProvider)
    {
    }

    public override async Task OnGetAsync()
    {
        await base.OnGetAsync();
        if (Id == Guid.Empty)
            ViewModel = new();
        else
        {
            var party = await ServiceProvider
                .GetRequiredService<IPartyBusiness>()
                .FetchPartyByIdAsync(Id, true);

            if (party != null)
            {
                ViewModel = party.Adapt<PartyViewModel>();
                ViewModel.PhoneNumbers = party.PhoneNumbers
                    .Select(item => item.Adapt<PartyPhoneViewModel>())
                    .ToList();
            }
        }
    }

    public async Task<IActionResult> OnPostParty([FromServices] IPartyBusiness partyBusiness)
    {
        if (!ModelState.IsValid)
            return Page();
        var result = await partyBusiness.AddOrUpdateParty(ViewModel);
        if (!result)
            return Page();
        return RedirectToPage("/");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 16:05:05