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

CKEditor文件上传接口断点响应正常但浏览器返回空列表问题

CKEditor文件上传接口返回空列表问题

我基于Stack Overflow代码实现了适配CKEditor的文件上传Controller Action,接口上传完成后应返回包含文件URL的JSON响应。调试时断点查看success对象结构符合预期,但浏览器端接收到的却是空列表。

Controller Action代码

[HttpPost]
public async Task<ActionResult> Upload(IFormFile upload, string CKEditorFuncNum, string CKEditor, string langCode)
{
    var user = await _userManager.GetUserAsync(User);
    var admin = _context.LeagueAdmins.Include(i => i.League).FirstOrDefault(i => i.User.Id == user.Id);
    if (user == null)
    {
        throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
    }

    if (upload.Length <= 0) return null;

    if (!upload.IsImage())
    {
        var NotImageMessage = "You must upload a picture";
        dynamic NotImage = JsonConvert.DeserializeObject("{ 'uploaded': 0, 'error': { 'message': \"" + NotImageMessage + "\"}}");
        return Json(NotImage);
    }

    var fileName = Guid.NewGuid() + Path.GetExtension(upload.FileName).ToLower();

    Image image = Image.FromStream(upload.OpenReadStream());
    int width = image.Width;
    int height = image.Height;
    if ((width > 2000) || (height > 2000))
    {
       var DimensionErrorMessage = "Your image is too big. It must be a maximum of 2000px height and width";
       dynamic stuff = JsonConvert.DeserializeObject("{ 'uploaded': 0, 'error': { 'message': \"" + DimensionErrorMessage + "\"}}");
       return Json(stuff);
    }

    if (upload.Length > 500 * 1024)
    {
       var LengthErrorMessage = "The file is too big. Maximum file size is 5mb";
       dynamic stuff = JsonConvert.DeserializeObject("{ 'uploaded': 0, 'error': { 'message': \"" + LengthErrorMessage + "\"}}");
       return Json(stuff);
    }
    var directory = Path.Combine(_env.WebRootPath, "uploads", admin.League.Id.ToString(), "pages");
    var path = Path.Combine(directory, fileName);

    if (!Directory.Exists(directory))
    {
         var mkdir = Directory.CreateDirectory(directory);
    }

    try
    {
        using (var stream = new FileStream(path, FileMode.Create))
        {
             await upload.CopyToAsync(stream);
        }
    }
    catch (Exception ex)
    {
        var exception = ex.Message;
    }
           
    var url = $"{"/uploads/" + admin.League.Id.ToString() + "/pages/"}{fileName}";
    var successMessage = "File is uploaded successfully";
    var success = JsonConvert.DeserializeObject("{ 'uploaded': 1,'fileName': \"" + fileName + "\" ,'url': \"" + url + "\" , 'error': { 'message': \"" + successMessage + "\"}}");
    return Json(success);
}

调试断点处的对象值

断点处的JSON对象

浏览器实际响应

浏览器返回的空列表


问题原因及解决方法

问题源于你用JsonConvert.DeserializeObject生成dynamic对象后,ASP.NET Core默认的System.Text.Json序列化器无法正确处理Newtonsoft.Json创建的动态对象,导致最终返回空列表。

方案1:使用强类型对象构建响应

定义符合CKEditor要求的响应类,避免使用dynamic:

public class CKEditorUploadResponse
{
    public int uploaded { get; set; }
    public string fileName { get; set; }
    public string url { get; set; }
    public CKEditorError error { get; set; }
}

public class CKEditorError
{
    public string message { get; set; }
}

修改成功响应代码:

var success = new CKEditorUploadResponse
{
    uploaded = 1,
    fileName = fileName,
    url = url,
    error = new CKEditorError { message = successMessage }
};
return Json(success);

错误响应部分同样替换为强类型对象,比如非图片的情况:

return Json(new CKEditorUploadResponse 
{ 
    uploaded = 0, 
    error = new CKEditorError { message = NotImageMessage } 
});

方案2:配置ASP.NET Core使用Newtonsoft.Json序列化

若要继续使用dynamic,需添加Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet包,然后在Program.cs中配置:

builder.Services.AddControllersWithViews()
    .AddNewtonsoftJson();

这样ASP.NET Core会用Newtonsoft.Json处理序列化,能正确识别之前的动态对象。

额外优化点

  • upload.Length <= 0时返回null不合理,建议返回标准错误响应:
    return Json(new CKEditorUploadResponse 
    { 
        uploaded = 0, 
        error = new CKEditorError { message = "上传文件为空" } 
    });
    
  • 图片流未释放,用using包裹:
    using (Image image = Image.FromStream(upload.OpenReadStream()))
    {
        int width = image.Width;
        int height = image.Height;
        // 尺寸判断逻辑
    }
    
  • 异常捕获后需返回错误响应,不要仅记录消息:
    catch (Exception ex)
    {
        return Json(new CKEditorUploadResponse 
        { 
            uploaded = 0, 
            error = new CKEditorError { message = $"文件上传失败:{ex.Message}" } 
        });
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 09:15:41