Delphi 10.4 DataSnap REST接口返回PDF被包装为JSON问题咨询
DataSnap REST服务返回PDF被序列化为JSON问题解决方案
问题根源
DataSnap默认会对服务端方法的所有返回值执行自动JSON序列化逻辑,你直接将TFileStream作为方法返回值时,序列化器会将流内的字节转换为整数数组,包装到标准{"result": [...]}的JSON结构中,即便你设置了正确的Content-Type响应头,实际响应体依然是JSON格式内容,因此会出现你遇到的问题。
修复方案
不要通过方法返回值传递文件流,直接操作调用元数据的响应流属性,跳过DataSnap的默认序列化逻辑,代码示例如下:
function TServerMethods1.GetPdf: Boolean; var fStream: TFileStream; meta: TDSInvocationMetadata; begin Result := False; meta := GetInvocationMetadata; try fStream := TFileStream.Create('images/ticket.pdf', fmOpenRead or fmShareDenyNone); // 直接绑定响应流,无需手动释放,DataSnap会在响应发送完成后自动回收 meta.ResponseContentStream := fStream; meta.ResponseContentType := 'application/pdf'; // 可选配置:控制客户端行为,inline为预览,attachment为直接下载 meta.SetCustomHeader('Content-Disposition', 'inline; filename="ticket.pdf"'); meta.ResponseCode := 200; Result := True; except on E: Exception do begin meta.ResponseCode := 500; meta.ResponseContentType := 'text/plain'; meta.ResponseContent := '文件加载失败: ' + E.Message; end; end; end;
额外注意事项
- 你之前在
WebModuleAfterDispatch中全局设置Content-Type的配置可以删除,该全局配置会影响其他正常返回JSON的接口,直接在方法内通过InvocationMetadata设置的响应参数优先级更高,只会作用于当前接口。 - 不需要手动释放赋值给
ResponseContentStream的流对象,DataSnap框架会在响应发送完成后自动执行释放操作,手动释放会导致响应发送时出现内存访问错误。
内容的提问来源于stack exchange,提问作者Pedro Luque
相关产品推荐
相关产品推荐

