如何将Java版Word转PDF POST请求移植为可被遗留数据库调用的C#实现
问题定位
之前两个C#版本的报错均来自和Java请求的行为不一致:
- 原生HttpClient版本:错误将
Content-Type添加到请求顶层Headers。按照HTTP协议规范,Content-Type是请求体的实体头,必须绑定到StreamContent的对应属性上;放在顶层的头会被HttpClient忽略,导致服务端收不到正确的请求体类型标识,直接返回500错误。Java的HttpURLConnection会自动将设置的Content-Type属性绑定到请求体上,因此Java版本不会出现该问题。 - RestSharp版本:
Converter-Job-Priority头的取值多了一个前导空格(传入值为" 1000"而非和Java一致的"1000"),同时手动设置全局Content-Type头再添加请求体参数,会出现重复的Content-Type头,干扰服务端的解析逻辑。
可运行的原生HttpClient实现(无第三方依赖,适配遗留数据库调用场景)
以下代码完全对齐Java版本的逻辑,无额外依赖,编译后可直接被外部程序、遗留数据库的外部调用接口触发执行:
using System; using System.IO; using System.Net; using System.Net.Http; class WordToPdfConverter { static void Main(string[] args) { // 接收参数逻辑和Java版本完全一致:第一个参数为Word源文件路径,第二个参数为PDF保存路径 if (args.Length < 2) { throw new ArgumentException("需传入两个参数:Word源文件路径、PDF目标保存路径"); } string sourceWordPath = args[0]; string targetPdfPath = args[1]; const string serverUrl = "http://localhost:9998"; // 兼容不同服务端的连接协议要求 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls; using var httpClient = new HttpClient(); using var fileStream = new FileStream(sourceWordPath, FileMode.Open, FileAccess.Read); // 构建请求 var request = new HttpRequestMessage(HttpMethod.Post, serverUrl) { Content = new StreamContent(fileStream) { // 将Content-Type正确绑定到请求体上 Headers = { ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/vnd.com.documents4j.any-msword") } }, // 顶层请求头存放和请求体无关的配置 Headers = { Accept = { new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/pdf") }, { "Converter-Job-Priority", "1000" } } }; // 发送请求 using var response = httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).Result; if (response.StatusCode != HttpStatusCode.OK) { throw new IOException($"转换失败,HTTP错误码:{response.StatusCode}"); } // 流式写入PDF文件,避免大文件占用过多内存 using var responseStream = response.Content.ReadAsStreamAsync().Result; using var pdfStream = new FileStream(targetPdfPath, FileMode.Create, FileAccess.Write); responseStream.CopyTo(pdfStream); Console.WriteLine($"PDF已成功保存至:{targetPdfPath}"); } }
修正后的RestSharp版本
如果项目已引入RestSharp依赖,可使用以下修正后的版本,修复之前的头错误:
using System; using System.IO; using System.Net; using RestSharp; using RestSharp.Extensions; class RestSharpWordToPdf { static void Main(string[] args) { string source = args[0]; string target = args[1]; var client = new RestClient("http://localhost:9998") { Timeout = -1 }; var request = new RestRequest(Method.POST); // 移除之前的多余空格,保持和Java版本完全一致 request.AddHeader("Accept", "application/pdf"); request.AddHeader("Converter-Job-Priority", "1000"); // 直接将文件字节作为请求体,自动绑定正确的Content-Type request.AddParameter("application/vnd.com.documents4j.any-msword", File.ReadAllBytes(source), ParameterType.RequestBody); IRestResponse response = client.Execute(request); Console.WriteLine($"响应状态码:{response.StatusCode}"); if (response.StatusCode != HttpStatusCode.OK) { // 打印具体错误内容方便排查 throw new Exception($"转换请求失败,状态码:{response.StatusCode}, 错误详情:{response.Content}"); } response.RawBytes.SaveAs(target); Console.WriteLine($"PDF已成功保存至:{target}"); } }
注意事项
- 实现全程发送Word文件的原始字节流,和Java版本的请求结构完全一致,不要额外添加表单、边界分隔符等冗余内容,否则会触发服务端解析错误。
- 部署时确保程序运行账号对Word源路径、PDF目标路径拥有读写权限。
- 如果修复头问题后仍出现500错误,可直接打印服务端返回的响应内容,定位服务端侧的具体异常原因。
内容的提问来源于stack exchange,提问作者Graeme Wellington
相关产品推荐
相关产品推荐

