Report Server: Export-Ergebnis als Stream via REST API abrufen

Mit Hilfe der Funktion ExportAsync der PreparedReport-Klasse lässt sich über die REST API des combit Report Servers ein Bericht erzeugen/exportieren. Als Ergebnis erhält man ein ExportResult-Objekt, dessen Methode DownloadFilesAsync verwendet werden kann, um den erzeugten Bericht in das Dateisystem herunterzuladen. Dieser Vorgang wird im mitinstallierten Programmierbeispiel ClientApi Sample der List & Label Installation durchgeführt - hier ein Auszug:

...
// Exports a report and downloads the files
private async Task ExportAndDownloadFiles(PreparedReport preparedExport)
{
    ExportResult result = await preparedExport.ExportAsync();

    MessageBox.Show("The export was completed and the files are ready for download, please choose a directory to save the file(s).");

    if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
    {
        await result.DownloadFilesAsync(folderBrowserDialog.SelectedPath, CancellationToken.None);
        if (MessageBox.Show("The report has been downloaded, would you like to open it?", "ClientAPI", MessageBoxButtons.YesNo) == DialogResult.Yes)
        {
            string reportFilePath = Path.Combine(folderBrowserDialog.SelectedPath, result.FirstPageFileLink.RelativeFilePath);
            Process.Start(new ProcessStartInfo(reportFilePath) { UseShellExecute = true });
        }
    }
}
...

Um nun jedoch keinen Download der Dateien in das Dateisystem durchführen zu müssen, bietet es sich an, den Bericht direkt in einen Stream zu laden. Das kann sehr nützlich sein, wenn man bspw. in einem Azure App Service unterwegs ist und kein Zugriff auf das Dateisystem besteht oder das Ergebnis über einen Stream direkt in ein Dokumentenmanagementsystem übertragen werden soll usw.

Damit der Download des Berichts in einen Stream erfolgen kann, kann man sich der Eigenschaft ExportedFileLinks bedienen. Hier sind alle Dateien des Berichts nach dem Export enthalten und können über die DownloadUri Methode über einen eigenen HttpClient direkt in einen Stream geladen werden:

...
// Exports a report and load the files into stream
public async Task DownloadFilesIntoStreamAsync(PreparedReport preparedExport)
{
    ExportResult result = await preparedExport.ExportAsync();

    List<Task> downloadJobs = new List<Task>();
    foreach (ExportedFileLink fileEntry in result.ExportedFileLinks)
    {
        Task downloadJob = Task.Run(async () =>
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Add("X-ReportServer-ClientId", "<Report Server REST API User>");
                httpClient.DefaultRequestHeaders.Add("X-ReportServer-ClientToken", "<Report Server REST API ClientToken>");

                using (var response = await httpClient.GetAsync(fileEntry.DownloadUri))
                {
                    Stream outputStream = new MemoryStream();
                    await response.Content.CopyToAsync(outputStream);
                }
            }
        });
        downloadJobs.Add(downloadJob);

    }
    await Task.WhenAll(downloadJobs);
}
...

Dabei ist wichtig, dass die Authentifizierung berücksichtigt wird, da mit einem eigenen HttpClient gearbeitet wird. Diese kann über zusätzliche Header-Einträge X-ReportServer-ClientId und X-ReportServer-ClientToken umgesetzt werden.

Weitere Informationen zur REST API des combit Report Servers finden sich in den beiden Namespaces combit.ReportServer.ClientApi und combit.ReportServer.ClientApi.Objects. Allgemeine Informationen zur REST API können dem Anwenderhanduch in Kapitel REST API entnommen werden.