问题
Question
I am attempting to download an SSRS report via its URL into a data buffer (byte array), so therefore I can then save it in a particular folder, with a name of my choosing. I am open to suggestions of different ways of doing this if required.
The Issue
However I am constantly getting the below error (401) Unauthorized, no matter which credentials I enter:
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.
I am using this code (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);
example URL (this downloads the file perfectly if I simply copy the below URL into my browser, no issues with the access whatsoever): http://ReportServer/ReportServer_MYSERVER/Pages/ReportViewer.aspx?%2fPurchaseOrder&rs:Command=Render&OrderID=100&rs:ClearSession=true&rs:Format=PDF
My machine is on a domain, and I have tried these credentials, along with the domain, and also the database SA account, but both deliver the same issue.
I know this code works when downloading a PDF file, as I hard-coded a random URL from the internet and this worked, for example: "http://www.axmag.com/download/pdfurl-guide.pdf"
Thankyou all for help on this matter, im hoping that this is possible as this would be a very handy addition to my application
回答1:
it turns out it was as simple as this for my scenario (using Default Credentials):
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);
this code above enables any SSRS report to be downloaded as a byte array. This then means that it can be saved in a specified location, with a name of your choice:
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
}
this next block is how you rename the file, and specify the location. I have also added a check to see if it already exists, if it does it simply does nothing.
I hope this helps as this is something I have been trying to get working for a long time!
回答2:
Using the ReportExecutionService class will be a best alternative solution. The chance of report getting failed to download is very less.
Every Microsoft SQL Server Reporting Server provide an SOAP End-point to ReportExecutionService. Third party application can use this extension to get connected to reporting server.
For .Net applications, using Visual Studio we can add Web Reference to the SOAP end-point http://(your_server_url)/reportserver/reportexecution2005.asmx (ReportExecutionService).
This will generate the necessary namepsaces and classed to the SOAP End-Point, which we can consume in our application to download the reports.
A Sample code is given below. The steps to add Web Reference, common errors and other details on this method can be found at
https://www.craftedforeveryone.com/download-sql-server-reporting-service-ssrs-report-as-pdf-using-c-sharp/
Note: We do not have NuGet Package or library available to resolve the namespace ReportExecutionService. Adding Web Reference to your Reporting server will resolve this.
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);
}
}
}
回答3:
Worked for me, only difference used 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);
来源:https://stackoverflow.com/questions/40338883/download-ssrs-report-and-save-in-specific-location-c-unauthorized