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

Blazor中使用MarkupString修改TelerikButton图标报错如何解决

报错原因分析
  • Blazor默认字符串转义机制
    直接在Razor模板中输出字符串变量时,Blazor会默认对所有HTML标签做转义处理,避免XSS注入风险,所以<i>标签会被转义为&lt;i&gt;这类纯文本字符,不会渲染为实际的DOM元素。
  • 直接修改[Parameter]标记的属性触发异常
    你将EyeIcon标记为了组件入参,但是在组件内部直接修改了这个参数的值。Blazor框架约定父组件传入的Parameter属性应由父组件负责维护,子组件内部直接修改会导致渲染树状态不一致,Telerik组件库的内部校验逻辑会直接抛出异常。
  • Razor语法冗余错误
    你写的@((MarkupString)@EyeIcon)中,EyeIcon前多了一个冗余的@符号,部分场景下会被Razor编译器识别为嵌套的表达式,触发语法解析错误。
  • TelerikButton子内容渲染逻辑冲突
    TelerikButton的ChildContent默认预期接收RenderFragment类型的渲染片段,直接传入MarkupString类型值时,可能和组件内部的子内容封装逻辑冲突,导致渲染异常。
可行解决方案

方案1:直接条件渲染图标(最推荐)

不要用字符串存HTML片段,直接用布尔变量控制图标渲染,完全规避类型转换问题:

<TelerikButton OnClick="@RevealPassword"
               Class="pass-btn"
               Primary="true"
               ButtonType="ButtonType.Button"
               Id="btnShowPwd"
               Title="Show">
    @if (HidePassword)
    {
        <i class='fal fa-eye fa-lg'></i>
    }
    else
    {
        <i class='fal fa-eye-slash fa-lg'></i>
    }
</TelerikButton>

@code {
    public bool HidePassword { get; set; } = true;

    public async Task RevealPassword()
    {
        HidePassword = false;
        await Task.Delay(2000);
        HidePassword = true;
    }

    [Parameter] public EventCallback<string> OnTypePassword { get; set; }
}

方案2:用RenderFragment类型定义图标参数

如果需要支持父组件传入自定义图标,将参数类型改为RenderFragment,不需要做任何类型转换即可正常渲染:

<TelerikButton OnClick="@RevealPassword"
               Class="pass-btn"
               Primary="true"
               ButtonType="ButtonType.Button"
               Id="btnShowPwd"
               Title="Show">
    @_currentIcon
</TelerikButton>

@code {
    [Parameter]
    public RenderFragment EyeIcon { get; set; } = @<i class='fal fa-eye fa-lg'></i>;

    private RenderFragment _currentIcon;
    private readonly RenderFragment _eyeSlashIcon = @<i class='fal fa-eye-slash fa-lg'></i>;

    protected override void OnInitialized()
    {
        _currentIcon = EyeIcon;
    }

    public async Task RevealPassword()
    {
        _currentIcon = _eyeSlashIcon;
        HidePassword = false;
        await Task.Delay(2000);
        HidePassword = true;
        _currentIcon = EyeIcon;
    }

    public bool HidePassword { get; set; } = true;
    [Parameter] public EventCallback<string> OnTypePassword { get; set; }
}

方案3:修正MarkupString用法

如果必须用HTML字符串存储图标,不要直接修改Parameter属性,新增内部私有变量存储当前图标字符串,再做类型转换:

<TelerikButton OnClick="@RevealPassword"
               Class="pass-btn"
               Primary="true"
               ButtonType="ButtonType.Button"
               Id="btnShowPwd"
               Title="Show">
    @((MarkupString)_currentEyeIcon)
</TelerikButton>

@code {
    [Parameter]
    public string EyeIcon { get; set; } = "<i class='fal fa-eye fa-lg'></i>";

    private string _currentEyeIcon;
    private const string _eyeSlashIcon = "<i class='fal fa-eye-slash fa-lg'></i>";

    protected override void OnInitialized()
    {
        _currentEyeIcon = EyeIcon;
    }

    public async Task RevealPassword()
    {
        _currentEyeIcon = _eyeSlashIcon;
        HidePassword = false;
        await Task.Delay(2000);
        HidePassword = true;
        _currentEyeIcon = EyeIcon;
    }

    public bool HidePassword { get; set; } = true;
    [Parameter] public EventCallback<string> OnTypePassword { get; set; }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 20:45:05