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

向WCF REST服务发送PDF时字节数组反序列化报错求助

问题分析与解决方案

核心问题

你遇到的反序列化错误,根源在于:

  1. 请求格式不匹配:WCF的DataContractJsonSerializer对byte[]类型的反序列化,期望接收Base64编码的字符串,而非你当前发送的数字数组。
  2. 请求体结构错误:你直接将数字数组作为请求体发送,但设置了Content-Type: application/json,实际发送的内容并非有效的JSON对象,导致WCF无法解析。
  3. URL构造不符合契约:你的请求URL缺少UriTemplate中要求的sessionToken路径参数,且未正确传递其他必填参数(如createApplication、option)。
  4. 同步XHR与异步语法冲突:你使用了await但XHR是同步模式,这会导致代码逻辑异常。

具体修复步骤

1. 将PDF文件转为Base64字符串

修改文件读取逻辑,直接读取为Base64格式并去掉前缀:

const file = e.target.files[0];
const reader = new FileReader();

reader.onloadend = async (e) => {               
    // 提取纯Base64字符串(去掉"data:application/pdf;base64,"前缀)
    const pdfBase64 = e.target.result.split(',')[1];
    
    let ret = await dispatch('createTemplate', {
        name: this.newForm.name, 
        pdfBase64: pdfBase64, 
        save: false,
        sessionToken: "你的会话令牌", // 替换为实际的sessionToken
        createApplication: false, // 根据需求设置
        option: "" // 根据需求设置
    });
    await this.$store.dispatch('hideLoadingScreen');
};

reader.onerror = async () => await this.$store.dispatch('hideLoadingScreen');
reader.onabort = async () => await this.$store.dispatch('hideLoadingScreen');
            
await this.$store.dispatch('showLoadingScreen');
reader.readAsDataURL(file);

2. 修正请求发送逻辑

构造符合要求的URL和JSON请求体,用Promise包装XHR以支持await:

async function createTemplate({ name, pdfBase64, save, sessionToken, createApplication, option }) {
    // 构造符合UriTemplate的URL,注意编码特殊字符
    const encodedName = encodeURIComponent(name);
    let url = `${getters.getServiceUrl}rest/${sessionToken}/ImportNewTemplate?commit=${save || true}&createApplication=${createApplication}&templateName=${encodedName}&option=${encodeURIComponent(option)}`;

    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open("POST", url, true);
        xhr.setRequestHeader('Content-Type', 'application/json');

        // 构造包含Base64字符串的JSON请求体
        const requestBody = JSON.stringify({
            templateFile: pdfBase64
        });

        xhr.onload = () => {
            if (xhr.status >= 200 && xhr.status < 300) {
                resolve(JSON.parse(xhr.responseText));
            } else {
                reject(new Error(`请求失败:状态码 ${xhr.status},响应:${xhr.responseText}`));
            }
        };

        xhr.onerror = () => reject(new Error("网络请求错误"));
        xhr.send(requestBody);
    });
}

3. 确认WCF服务配置(可选)

如果服务端未显式配置请求格式,确保WebInvoke属性包含RequestFormat = WebMessageFormat.Json:

[WebInvoke(
    UriTemplate = "rest/{sessionToken}/ImportNewTemplate?commit={commit}&createApplication={createApplication}&templateName={templateName}&option={option}",
    Method = "POST",
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json
)]

关键说明

  • WCF的DataContractJsonSerializer默认将byte[]序列化为Base64字符串,因此反序列化时也必须传入Base64格式的字符串,而非数字数组。
  • 所有URL中的参数(如templateName)必须用encodeURIComponent编码,避免特殊字符导致的路由错误。
  • 必须使用异步XHR并通过Promise包装,才能正确配合await语法使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 06:36:26