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

如何在Blazor页面路由中使用强类型领域模型作为参数?

在Blazor中实现强类型领域ID的路由参数绑定

完全可以通过**自定义类型转换器(TypeConverter)**实现这个需求,这是Blazor原生支持的机制,无需在页面中手动转换,实现一次即可复用所有强类型ID。

实现步骤

1. 为强类型ID添加TypeConverter属性

给你的领域ID结构体标记[TypeConverter]属性,指定对应的转换器类型。如果有多个同类型基础值的ID(比如都是int类型的AccountId、OrderId),可以用泛型转换器复用逻辑。

单ID转换器示例

先定义AccountId并绑定转换器:

using System.ComponentModel;

[TypeConverter(typeof(AccountIdConverter))]
public readonly record struct AccountId(int Value);

然后实现AccountIdConverter:

public class AccountIdConverter : TypeConverter
{
    // 支持从字符串转换为AccountId
    public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override object? ConvertFrom(ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object value)
    {
        if (value is string str && int.TryParse(str, out var id))
        {
            return new AccountId(id);
        }
        return base.ConvertFrom(context, culture, value);
    }

    // 支持从AccountId转换为字符串(用于生成路由链接等场景)
    public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType)
    {
        return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
    }

    public override object? ConvertTo(ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object? value, Type destinationType)
    {
        if (destinationType == typeof(string) && value is AccountId accountId)
        {
            return accountId.Value.ToString();
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}

泛型转换器复用(推荐)

如果有多个基于int的强类型ID,定义一个通用接口和泛型转换器避免重复代码:

// 定义基础接口
public interface IIntId
{
    int Value { get; }
}

// AccountId实现接口并绑定泛型转换器
[TypeConverter(typeof(IntIdConverter<AccountId>))]
public readonly record struct AccountId(int Value) : IIntId;

// OrderId同理
[TypeConverter(typeof(IntIdConverter<OrderId>))]
public readonly record struct OrderId(int Value) : IIntId;

实现泛型转换器:

public class IntIdConverter<T> : TypeConverter where T : struct, IIntId
{
    public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override object? ConvertFrom(ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object value)
    {
        if (value is string str && int.TryParse(str, out var id))
        {
            // 通过反射创建强类型ID实例
            return Activator.CreateInstance(typeof(T), id);
        }
        return base.ConvertFrom(context, culture, value);
    }

    public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType)
    {
        return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
    }

    public override object? ConvertTo(ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object? value, Type destinationType)
    {
        if (destinationType == typeof(string) && value is IIntId intId)
        {
            return intId.Value.ToString();
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}

2. 在Blazor组件中直接使用强类型参数

完成转换器实现后,你可以直接在组件中声明强类型参数,路由约束保持不变(或去掉约束也可,转换器会自动处理):

@page "/accounts/{accountId:int}"

<h3>Account Details</h3>

@code {
    [Parameter]
    public AccountId AccountId { get; set; }

    protected override void OnInitialized()
    {
        // 直接使用AccountId.Value即可,无需手动转换
        Console.WriteLine($"Loading account with ID: {AccountId.Value}");
    }
}

原理说明

Blazor的路由参数绑定系统会自动检查参数类型是否带有TypeConverter属性,如果有,则使用转换器完成字符串(路由参数的原始类型)到强类型ID的转换,完全无需在页面中写额外的转换逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 21:31:13