Chrome扩展通过WCF上传Word文档后格式错乱的解决方法
问题分析与修复方案
问题根源
你的Word文档上传后格式错乱,核心原因是WCF服务的请求格式配置与前端发送的请求格式不匹配:
- WCF接口设置了
RequestFormat = WebMessageFormat.Json,期望接收Json格式数据 - 前端用
FormData发送multipart/form-data格式的二进制文件 - 这种不匹配导致WCF错误地将二进制文件流当成Json解析,破坏了docx文件的二进制结构(docx本质是ZIP压缩包,任何额外的字符或格式错误都会导致文件损坏)
修复方案
提供两种可行的修复方式,根据你的需求选择:
方案一:支持FormData上传(可同时传递文件名等额外参数)
1. 修改WCF服务契约
调整WebInvoke属性,移除Json请求格式,改为接受原始请求,并通过HttpContext解析FormData:
[OperationContract] [WebInvoke(Method = "POST", UriTemplate = "/UploadFile", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] string UploadFile();
2. 修改服务实现方法
直接从HttpContext读取FormData中的文件和参数,避免解析错误:
public string UploadFile() { try { var request = HttpContext.Current.Request; // 验证请求格式 if (!request.ContentType.StartsWith("multipart/form-data")) { return "false: 无效的请求格式"; } // 检查是否有上传文件 if (request.Files.Count == 0) { return "false: 未选择上传文件"; } // 获取上传的文件和文件名 var uploadedFile = request.Files["fileStream"]; string fileName = request.Form["fileName"] ?? "Test.docx"; string savePath = Path.Combine(HostingEnvironment.MapPath("~/Uploads"), fileName); // 保存文件 uploadedFile.SaveAs(savePath); return "true"; } catch (Exception ex) { string errorLogPath = Path.Combine(HostingEnvironment.MapPath("~/"), "error.txt"); File.WriteAllText(errorLogPath, $"{ex.StackTrace}\n{ex.Message}"); return "false"; } }
3. 前端代码(无需修改)
保持你的原有FormData上传逻辑,只需补充正确的wcfServiceUrl即可。
方案二:直接上传二进制流(更高效,适合仅传文件场景)
这种方式跳过FormData,直接传递文件原始二进制流,减少解析开销。
1. 修改WCF服务契约
通过URL参数传递文件名,接受原始二进制流:
[OperationContract] [WebInvoke(Method = "POST", UriTemplate = "/UploadFile?fileName={fileName}", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] string UploadFile(string fileName, Stream fileStream);
2. 服务实现方法
直接将原始流写入文件,避免格式转换:
public string UploadFile(string fileName, Stream fileStream) { try { string savePath = Path.Combine(HostingEnvironment.MapPath("~/Uploads"), fileName ?? "Test.docx"); using (FileStream writer = new FileStream(savePath, FileMode.Create)) { int readCount; byte[] buffer = new byte[8192]; while ((readCount = fileStream.Read(buffer, 0, buffer.Length)) != 0) { writer.Write(buffer, 0, readCount); } } return "true"; } catch (Exception ex) { string errorLogPath = Path.Combine(HostingEnvironment.MapPath("~/"), "error.txt"); File.WriteAllText(errorLogPath, $"{ex.StackTrace}\n{ex.Message}"); return "false"; } }
3. 修改前端代码
直接发送文件二进制流,设置正确的请求头:
document.getElementById('uploadResume').addEventListener('click', function () { const fileInput = document.getElementById('fileInput'); const file = fileInput.files[0]; if (file) { const xhr = new XMLHttpRequest(); // 替换为你的WCF服务地址,通过URL传递文件名 const wcfServiceUrl = `你的WCF服务地址/UploadFile?fileName=${encodeURIComponent(file.name)}`; xhr.open('POST', wcfServiceUrl, true); // 设置二进制流的内容类型 xhr.setRequestHeader('Content-Type', 'application/octet-stream'); xhr.onload = function () { if (xhr.status === 200) { console.log('文件上传成功'); console.log(xhr.responseText); } else { console.error('文件上传失败'); } }; // 直接发送文件原始二进制流 xhr.send(file); } else { console.error('未选择文件'); } });
验证注意事项
- 确保WCF服务的
web.config中配置了支持流传输的绑定(比如webHttpBinding,并设置maxReceivedMessageSize足够大) - 测试时上传docx文件后,打开检查是否正常,若仍有问题,可对比原文件和上传后文件的大小,若大小差异大,说明仍有额外数据写入
内容的提问来源于stack exchange,提问作者Kunal
相关产品推荐
相关产品推荐

