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

如何在C#中实现JS版RetrieveEntityReq执行SSRS报表并获取Base64数据

解决C#中执行SSRS报表并转换为Base64 PDF附件的问题

我明白你现在的处境——原来在JS里用XMLHttpRequest发POST请求执行报表、转Base64当PDF附件的流程跑通了,但转到C#时踩了不少坑:RetrieveEntityRequest完全不对路子(它本来就是拿系统元数据的),HttpWebRequest返回OK却没内容,最后只能用发布报表后渲染的替代方案。下面我给你梳理正确的实现方式,顺便排查你之前的问题:

先说说你之前的坑点

  • RetrieveEntityRequest:这个是Dynamics 365这类平台用来检索实体元数据的API,和SSRS报表执行半毛钱关系都没有,方向完全错了
  • HttpWebRequest返回空内容:大概率是请求端点、请求头、参数或者身份验证没配置对,SSRS的报表执行有特定的API格式,不是随便发个POST就行

1. 直接模拟JS逻辑的C#实现(调用SSRS执行API)

SSRS支持SOAP和REST两种API来执行报表,这里用SOAP方式和你JS里的POST逻辑最匹配:

using System;
using System.IO;
using System.Net;
using System.Text;

public string ExecuteReportToBase64Pdf(string reportServerUrl, string reportPath, string username, string password)
{
    // SSRS的报表执行SOAP端点,一般是ReportExecution2005.asmx
    string executionEndpoint = $"{reportServerUrl.TrimEnd('/')}/ReportExecution2005.asmx";
    
    // 构建SOAP请求体,指定报表路径、输出格式为PDF
    string soapBody = $@"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
  <soap:Body>
    <Render xmlns=""http://schemas.microsoft.com/sqlserver/reporting/2005/06/30/reportexecution/"">
      <Report>{reportPath}</Report>
      <Format>PDF</Format>
      <DeviceInfo></DeviceInfo>
      <Parameters></Parameters>
      <Credentials>
        <CredentialsXml><UserCredentials><UserName>{username}</UserName><Password>{password}</Password></UserCredentials></CredentialsXml>
      </Credentials>
    </Render>
  </soap:Body>
</soap:Envelope>";

    var request = (HttpWebRequest)WebRequest.Create(executionEndpoint);
    request.Method = "POST";
    request.ContentType = "text/xml; charset=utf-8";
    // 必须指定SOAPAction头,否则SSRS不认
    request.Headers.Add("SOAPAction", "http://schemas.microsoft.com/sqlserver/reporting/2005/06/30/reportexecution/Render");
    
    // 如果报表服务器用Windows身份验证,启用下面两行
    // request.Credentials = new NetworkCredential(username, password);
    // request.PreAuthenticate = true;

    // 写入请求体
    using (var writer = new StreamWriter(request.GetRequestStream()))
    {
        writer.Write(soapBody);
    }

    // 获取响应并处理PDF流
    using (var response = (HttpWebResponse)request.GetResponse())
    {
        if (response.StatusCode != HttpStatusCode.OK)
        {
            throw new InvalidOperationException($"请求失败:{response.StatusDescription}");
        }

        using (var responseStream = response.GetResponseStream())
        {
            if (responseStream == null) throw new InvalidOperationException("未获取到报表内容");
            
            var memoryStream = new MemoryStream();
            responseStream.CopyTo(memoryStream);
            // 转成Base64字符串
            return Convert.ToBase64String(memoryStream.ToArray());
        }
    }
}

2. 解决你之前HttpWebRequest无内容的排查要点

  • 端点正确性:确认用的是ReportExecution2005.asmx而不是报表查看的页面URL
  • 请求头配置:SOAP请求必须加SOAPAction头;如果用REST端点(比如/api/v2.0/reports/{reportPath}/Render),要加Accept: application/pdf
  • 身份验证:如果是Windows验证,一定要设置NetworkCredential;如果是Forms验证,得先登录拿到Cookie再附在请求里
  • 报表参数:如果报表需要参数,要在SOAP请求的<Parameters>节点里添加,比如:
    <Parameters>
      <ParameterValue>
        <Name>StartDate</Name>
        <Value>2024-01-01</Value>
      </ParameterValue>
    </Parameters>
    

3. 关于你用的替代方案(发布报表后渲染)

这个方案其实也是可行的,而且可以用SSRS官方的客户端库简化代码,不需要自己拼SOAP请求:

using Microsoft.Reporting.WebForms;
using System.IO;

public string RenderPublishedReportToBase64(string reportServerUrl, string reportPath)
{
    using var reportViewer = new ReportViewer();
    reportViewer.ServerReport.ReportServerUrl = new Uri(reportServerUrl);
    reportViewer.ServerReport.ReportPath = reportPath;
    
    // 给报表传参数(如果需要)
    // reportViewer.ServerReport.SetParameters(new ReportParameter("EndDate", "2024-06-01"));
    
    // 直接渲染成PDF字节数组
    byte[] pdfBytes = reportViewer.ServerReport.Render("PDF");
    return Convert.ToBase64String(pdfBytes);
}

注意:要使用这个方法,需要安装Microsoft.Reporting.WebForms的NuGet包,并且确保项目目标框架和库兼容。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:22:36