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

Blazor中如何为EditForm传递Tuple等非对象类型作为Model?

Can Blazor's EditForm Model Accept a Tuple or Non-Object Type?

Great question! Let's break down how this works in Blazor's EditForm and what your options are.

First, a quick note: By design, EditForm's Model property expects a reference type object. This is because Blazor's form binding and validation systems rely on .NET reflection to track property changes, apply validation attributes, and sync values between the form and your data source. Value types like ValueTuple (C# 7+) or primitive types (int, string) work differently here, so using them directly comes with limitations.


The most reliable and clean approach is to create a simple wrapper class that holds your tuple values or primitive type. This lets you use all of Blazor's form features (like data annotations validation) without workarounds.

Example for a Tuple:

If you wanted to use (int Id, string Name) as your form data, create a class:

public class UserFormModel
{
    [Required(ErrorMessage = "ID is required")]
    public int Id { get; set; }

    [Required(ErrorMessage = "Name is required")]
    [StringLength(50)]
    public string Name { get; set; } = string.Empty;
}

Then use it in your EditForm:

@code {
    private UserFormModel _model = new();

    private void HandleValidSubmit()
    {
        // Use _model.Id and _model.Name here
    }
}

<EditForm Model="@_model" OnValidSubmit="HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <InputNumber @bind-Value="_model.Id" />
    <ValidationMessage For="@(() => _model.Id)" />

    <InputText @bind-Value="_model.Name" />
    <ValidationMessage For="@(() => _model.Name)" />

    <button type="submit">Submit</button>
</EditForm>

Example for a Primitive Type (e.g., int):

If you just need to bind a single integer, wrap it in a class:

public class IntFormModel
{
    [Range(1, 100, ErrorMessage = "Value must be between 1 and 100")]
    public int Value { get; set; }
}

Option 2: Use a Tuple Directly (With Caveats)

If you really need to use a ValueTuple directly, it's possible—but you'll lose some key features and need manual workarounds.

Key Limitations:

  • No validation attributes: You can't apply [Required] or other validation attributes to tuple members.
  • Value type copying: Since ValueTuple is a value type, the EditForm receives a copy of your tuple. Changes to the form won't automatically sync back to your original variable.

How to Make It Work:

@code {
    private (int Id, string Name) _originalTuple = (1, "Test");
    private EditForm? _editForm;

    private void HandleSubmit()
    {
        // Manually sync the modified tuple back to your original variable
        if (_editForm?.Model is (int Id, string Name) modifiedTuple)
        {
            _originalTuple = modifiedTuple;
        }
    }
}

<EditForm @ref="_editForm" Model="@_originalTuple" OnSubmit="HandleSubmit">
    <InputNumber @bind-Value="_originalTuple.Id" />
    <InputText @bind-Value="_originalTuple.Name" />

    <button type="submit">Submit</button>
</EditForm>

This works, but it's not ideal—you miss out on validation and have to handle sync manually. Stick with the wrapper class unless you have a specific reason not to.


Final Takeaway

Blazor's EditForm is designed around reference type models, so wrapping your tuple or value type in a class is the best way to get full functionality (validation, automatic binding sync). Using tuples directly is possible but comes with tradeoffs that make it less maintainable.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:57:30