下载 SSRS 报告并保存在特定位置(C#)(未经授权)

Download SSRS Report and save in specific location (C#) (Unauthorized)

问题

我正在尝试通过 URL 将 SSRS 报告下载到数据缓冲区(字节数组)中,因此我可以将其保存在特定文件夹中,并使用我选择的名称。如果需要,我愿意接受不同方法的建议。

问题

然而,无论我输入哪种凭据,我都不断收到以下错误 (401) 未经授权

An exception of type 'System.Net.WebException' occurred in System.dll but was not handled in user code

Additional information: The remote server returned an error: (401) Unauthorized.

我正在使用此代码 (C#):

WebClient myWebClient = new WebClient();
NetworkCredential netCredential = new NetworkCredential("username", "password");
myWebClient.Credentials = netCredential;

var theURL = "http://ReportServer/ReportServer_MYSERVER/Pages/ReportViewer.aspx?%2fPurchaseOrder&rs:Command=Render&OrderID=100&rs:ClearSession=true&rs:Format=PDF"

byte[] myDataBuffer = myWebClient.DownloadData(theURL);

示例 URL(如果我只是将下面的 URL 复制到我的浏览器中,这将完美地下载文件,访问没有任何问题):http://ReportServer/ReportServer_MYSERVER/Pages/ReportViewer.aspx?%2fPurchaseOrder&rs:Command=Render&OrderID=100&rs:ClearSession=true&rs:Format=PDF

我的机器在一个域上,我已经尝试了这些凭据以及域和数据库 SA 帐户,但都出现了同样的问题。

我知道这个代码在下载 PDF 文件时有效,因为我从互联网上硬编码了一个随机 URL 并且这个有效,例如:“http://www.axmag.com/download/pdfurl-guide.pdf

谢谢大家在这件事上的帮助,我希望这是可能的,因为这对我的申请来说是一个非常方便的补充

事实证明,对于我的场景(使用默认凭据)来说就这么简单:

var theURL = "http://ReportServer/ReportServer_MYSERVER/Pages/ReportViewer.aspx?%2fPurchaseOrder&rs:Command=Render&OrderID=100&rs:ClearSession=true&rs:Format=PDF";

WebClient Client = new WebClient();
Client.UseDefaultCredentials = true;

byte[] myDataBuffer = Client.DownloadData(theURL);

上面的代码可以将任何 SSRS 报告下载为字节数组。这意味着它可以保存在指定位置,名称由您选择:

var filename = "Test.PDF";
var fileStructureLocal = "C:\Test";
var fileStructureNetwork = "\\NetworkDrive\TestFolder";

var fileLocation = fileStructureNetwork + "\" + filename;

 if (System.IO.File.Exists(url) == true)
        {
            //DO NOTHING
        }
 else
        {
            System.IO.File.WriteAllBytes(url, myDataBuffer);
            //SAVE FILE HERE
        }

下一个块是您如何重命名文件并指定位置。我还添加了一个检查以查看它是否已经存在,如果它存在则什么都不做。

我希望这对您有所帮助,因为这是我长期以来一直努力工作的事情!

使用 ReportExecutionService class 将是最佳替代解决方案。报告下载失败的几率非常小

每个 Microsoft SQL 服务器报告服务器都为 ReportExecutionService 提供一个 SOAP 端点。第三方应用程序可以使用此扩展程序连接到报告服务器。

对于 .Net 应用程序,使用 Visual Studio 我们可以将 Web 引用添加到 SOAP 端点 http://(your_server_url)/reportserver/reportexecution2005.asmx (ReportExecutionService)。

这将生成必要的命名空间并classed 到 SOAP 端点,我们可以在我们的应用程序中使用它来下载报告。

下面给出了示例代码。添加 Web 引用的步骤、常见错误和有关此方法的其他详细信息可在

中找到

https://www.craftedforeveryone.com/download-sql-server-reporting-service-ssrs-report-as-pdf-using-c-sharp/

注意:我们没有可用于解析命名空间 ReportExecutionService 的 NuGet 包或库。将 Web 引用添加到您的报告服务器将解决此问题。

using DownloadSSRSReport.craftedforeveryone.com;
using System.Collections.Generic;
using System.IO;
using System.Net;

namespace DownloadSSRSReport
{
class Program
{
static void Main(string[] args)
{
ReportExecutionService rs = new ReportExecutionService();
rs.Credentials = CredentialCache.DefaultCredentials;
rs.Url = "http://craftedforeveryone.com/reportserver/reportexecution2005.asmx";

rs.ExecutionHeaderValue = new ExecutionHeader();
var executionInfo = new ExecutionInfo();
executionInfo = rs.LoadReport("/your report path/report name", null);

List<ParameterValue> parameters = new List<ParameterValue>();

parameters.Add(new ParameterValue { Name = "parameterId", Value = "value" });

rs.SetExecutionParameters(parameters.ToArray(), "en-US");


string deviceInfo = "<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
string mimeType;
string encoding;
string[] streamId;
Warning[] warning;

var result = rs.Render("PDF", deviceInfo, out mimeType, out encoding, out encoding, out warning, out streamId);
File.WriteAllBytes("c:\temp\report.pdf", result);

}
}
}

对我有用,唯一不同的是使用了 HTTPClient

var theURL = "http://ReportServer/ReportServer_MYSERVER/Pages/ReportViewer.aspx?%2fPurchaseOrder&rs:Command=Render&OrderID=100&rs:ClearSession=true&rs:Format=PDF";

var httpClientHandler = new HttpClientHandler()
                                    {
                                        UseDefaultCredentials = true
                                    };

            HttpClient webClient = new HttpClient(httpClientHandler);

            byte[] response = await webClient.GetByteArrayAsync(theURL);

我在 vb.net 中使用自定义身份验证编写如下,

     
private sub GenerateReportPDF () 
 Dim username As String = "username"
          Dim password As String = "password"
          Dim strURL As String = $"https://server/ReportServer/Pages/ReportViewer.aspx?Report&param1=" + Param1 + "&Param2=" + Param1 + "&rs:Format=PDF"

          'prepare the request'
          Dim req As WebClient = New WebClient()
          req.Credentials = CredentialCache.DefaultCredentials
          req.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials
          req.UseDefaultCredentials = True

          Dim myCache As New CredentialCache()
          myCache.Add(New Uri($"https://server/reportserver"), "NTLM", New System.Net.NetworkCredential(username, password, "domainName"))
          req.Credentials = myCache

          'prepare the response'
          Dim myResponse As HttpResponse = HttpContext.Current.Response
          myResponse.Clear()
          myResponse.ClearContent()
          myResponse.ClearHeaders()
          myResponse.Buffer = True
          myResponse.ContentType = "application/pdf"
          myResponse.BinaryWrite(req.DownloadData(strURL))
          myResponse.End()
End Sub