React JS集成unLayer email-editor无法加载数据库存储设计的问题排查
问题根因
核心故障是后端接口对JSON内容做了双重序列化,和React组件本身的生命周期逻辑无关。
你存储在数据库NVARCHAR字段里的DesignStructure本身已经是符合unLayer规范的JSON字符串,C#默认的Json()序列化方法会把传入的所有值(包括已经是JSON格式的字符串)当做普通对象值再次序列化:最终返回结果会被包裹在数组里,字符串内部的双引号全部被反斜杠转义,前端拿到的不是unLayer loadDesign 方法要求的原生结构化对象,读取内部属性时自然会抛出TypeError: Cannot read properties of undefined (reading 'values')。至于ReferenceError("this hasn't been initialised - super() hasn't been called")是编辑器加载失败触发的连带报错,不是独立问题。
修复方案
1. 后端代码修正
首先修正服务层的不合理写法:你当前返回string[]数组、手动new Task启动线程的写法既不符合单条查询的需求,也存在EF上下文线程安全隐患。
- 服务层改为直接返回单条字符串,用EF原生异步方法查询:
public async Task<string> RetrieveNewsletterDesignById(int designId) { using var context = new HubbleDBContext(); var designStructure = await context.eNewsLetterDesigns .Where(soughtNewsLetterDesign => soughtNewsLetterDesign.DesignId == designId) .Select(soughtNewsLetterDesign => soughtNewsLetterDesign.DesignStructure) .FirstOrDefaultAsync(); return designStructure; }
- 控制器层不要用
Json()方法对已经成型的JSON字符串做二次序列化,直接返回原生JSON内容即可:
public async Task<ActionResult> RetrieveNewsletterDesignById(int designId) { try { string designJson = await newslettersService.RetrieveNewsletterDesignById(designId); return Content(designJson, "application/json"); } catch (Exception exception) { return LoggedError(exception); } }
验证点:改完后查看浏览器Network面板的接口响应,应该直接返回
{"counters":{...},"body":{...}}结构,没有外层数组包裹,没有多余的反斜杠转义符。
2. 前端增加兼容容错
为了避免后续因为返回格式波动导致加载失败,前端加一层类型判断,兼容字符串/对象两种返回格式:
NewsletterService.RetrieveNewsletterDesignById(selectedDesignId) .then((data) => { if (!data || data === 'FAIL' || !this.mounted || !this.editor) return; // 如果返回的是序列化后的字符串,先解析为JS对象再传入编辑器 const designData = typeof data === 'string' ? JSON.parse(data) : data; this.editor.loadDesign(designData); }) .catch(err => console.error("邮件模板加载失败", err));
改完后编辑器会正常加载存储的模板内容,两个运行时报错都会消失。
内容的提问来源于stack exchange,提问作者kevmull
相关产品推荐
相关产品推荐

