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

如何解决TinyMCE Blazor自定义图片上传处理器的JSON序列化错误?

解决TinyMCE Blazor自定义图片上传(带JWT认证)的序列化问题

问题核心在于TinyMCE Blazor会将配置字典序列化为JSON传递给JS端,C#的Lambda/委托无法被JSON序列化,所以不能直接把C#逻辑塞到images_upload_handler里。下面是可行的解决方案:

步骤1:调整TinyMCE配置,引用JS全局上传函数

修改Razor页面的配置,将images_upload_handler设为JS全局函数的名称,而非C#代码:

@inject IJSRuntime JS
@inject AuthenticationStateProvider AuthState

<TinyMCE EditorConf="@editorConf" />

@code {
    private Dictionary<string, object> editorConf = new Dictionary<string, object>
    {
        {"plugins", "autolink media link image emoticons table paste"},
        {"toolbar", "undo redo | styles | bold italic underline | table | link image paste "},
        {"paste_data_images", "true"},
        {"width", "100%"},
        {"automatic_uploads", true},
        // 指定JS全局函数作为上传处理器
        {"images_upload_handler", "tinymceImageUploadHandler"}
    };

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            // 从认证状态中获取JWT,传递给JS(如果JWT存在localStorage可跳过这步)
            var authState = await AuthState.GetAuthenticationStateAsync();
            var jwtToken = authState.User.FindFirst("access_token")?.Value;
            if (!string.IsNullOrEmpty(jwtToken))
            {
                await JS.InvokeVoidAsync("setTinyMCEUploadToken", jwtToken);
            }
        }
    }
}

步骤2:编写JS上传处理器,添加JWT认证

在wwwroot/scripts/tinymce-upload.js中编写全局上传函数,负责添加JWT并调用后端接口:

// 存储JWT(如果从C#传递)
let uploadToken = '';

// 接收C#传递的JWT
window.setTinyMCEUploadToken = function(token) {
    uploadToken = token;
};

// TinyMCE上传处理器核心逻辑
window.tinymceImageUploadHandler = function(blobInfo, success, failure, progress) {
    // 若JWT存在localStorage,可直接读取:
    // const uploadToken = localStorage.getItem('your_token_key');

    const formData = new FormData();
    formData.append('file', blobInfo.blob(), blobInfo.filename());

    fetch('/UploadImage/', {
        method: 'POST',
        headers: {
            // 添加JWT认证头
            'Authorization': `Bearer ${uploadToken}`
        },
        body: formData
    })
    .then(response => {
        if (!response.ok) throw new Error('图片上传失败');
        return response.json();
    })
    .then(data => {
        // 将后端返回的图片路径传给TinyMCE
        success(data.location);
    })
    .catch(error => {
        failure(error.message);
    });
};

步骤3:在页面引入JS脚本

在wwwroot/index.html中添加脚本引用:

<script src="scripts/tinymce-upload.js"></script>

步骤4:后端上传接口示例(带JWT认证)

确保后端接口支持JWT认证,并处理文件上传:

[ApiController]
[Route("UploadImage")]
[Authorize]
public class UploadImageController : ControllerBase
{
    private readonly IWebHostEnvironment _webHostEnv;

    public UploadImageController(IWebHostEnvironment webHostEnv)
    {
        _webHostEnv = webHostEnv;
    }

    [HttpPost]
    public async Task<IActionResult> Upload(IFormFile file)
    {
        if (file == null || file.Length == 0)
            return BadRequest("未选择上传文件");

        // 创建上传目录
        var uploadDir = Path.Combine(_webHostEnv.WebRootPath, "uploads/images");
        Directory.CreateDirectory(uploadDir);

        // 生成唯一文件名
        var fileName = $"{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
        var filePath = Path.Combine(uploadDir, fileName);

        // 保存文件
        using var stream = new FileStream(filePath, FileMode.Create);
        await file.CopyToAsync(stream);

        // 返回图片访问路径
        return Ok(new { location = $"/uploads/images/{fileName}" });
    }
}

为什么原来的方案报错?

你之前的代码试图把C# Lambda赋值给images_upload_handler,但TinyMCE Blazor需要将配置序列化为JSON传递给JS,而C#的委托/Lambda类型无法被JSON序列化,因此抛出序列化错误。必须使用JS层面的函数作为上传处理器,再通过JS与C#交互或直接调用后端接口。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 00:01:20