Why does my Asp.Net API not like my ReportViewer

Viewed 66

I have a UWP app that is calling to a Asp.net API. I am trying to get the API to fetch a PDF from a SQL ReportServer and return it to the UWP app.

My API controller method:

[HttpGet]
[Route("invoicereport/{report}/{invoice}")]
public IHttpActionResult GetInvoiceReport([FromUri] string report, [FromUri] string invoice)
{
    try
    {
        Debug.WriteLine("Test");

        ReportViewer ReportViewer1 = new ReportViewer();

        ReportViewer1.ProcessingMode = ProcessingMode.Remote;

        ReportViewer1.ServerReport.ReportServerUrl = new Uri("http://localhost/ReportServer");

        ReportViewer1.ServerReport.ReportPath = $"/{ReportsDir}/Invoice/{report}";

        ReportParameter[] rptParams = new ReportParameter[2];

        rptParams[0] = new ReportParameter("SOPNUMBER", invoice);
        rptParams[1] = new ReportParameter("SOPTypeString", "Invoice");

        ReportViewer1.ServerReport.SetParameters(rptParams);

        string format = "PDF", devInfo = @"<DeviceInfo><Toolbar>True</Toolbar></DeviceInfo>";

        string mimeType = "",
            encoding = "",
            fileNameExtn = "";
        string[] stearms = null;
        Warning[] warnings = null;

        byte[] result = null;

   
        //render report, it will returns bite array

        result = ReportViewer1.ServerReport.Render(format,
            devInfo, out mimeType, out encoding,
            out fileNameExtn, out stearms, out warnings);

        //create file with require legth

        //var pdf = PdfDocument.LoadFromStreamAsync(result);

        FileStream stream = File.Create(Path.GetTempPath() + $"/Reports/{invoice}.pdf", result.Length);

        //write file with rendered result

        stream.Write(result, 0, result.Length);

        //close stream

        stream.Close();

        var file = StorageFile.GetFileFromPathAsync(Path.GetTempPath() + $"/Reports/{invoice}.pdf");

        var pdf = PdfDocument.LoadFromFileAsync(file.GetResults());

        return Ok(pdf.GetResults());

    }
    catch (Exception ex)
    {
        Log.Logger.Error(ex,"Reporting Error");
    }

    return Ok();
}

When the method is called, it immediately errors and returns. I have a breakpoint on the Debug line it never reaches. The Debug line or the try-catch doesn't log anything.

The debug window output:

...
Exception thrown: 'System.Web.HttpException' in System.Web.Mvc.dll
Exception thrown: 'System.Web.HttpException' in System.Web.dll
Exception thrown: 'System.Net.WebException' in System.Net.Requests.dll
Exception thrown: 'System.Net.WebException' in System.Private.CoreLib.dll
Exception thrown: 'System.Net.WebException' in System.Net.Requests.dll
Exception thrown: 'System.Xml.XmlException' in System.Private.Xml.dll
...

As near as I can tell, it doesn't like the Microsoft.Reporting.WebForms.ReportViewer. Other actions/methods in this controller are working fine. I know this is not technically a WebForm, but I am stuck on what to do next. Any hints or just a shove in the right direction will be appreciated.

1 Answers

After a few more hours of frustration...

I changed to accessing the ReportServer using a SOAP WebService

[HttpGet]
[Route("invoicereport/{report}/{invoice}")]
public async Task<IHttpActionResult> GetInvoiceReport([FromUri] string report, [FromUri] string invoice)
{
    try
    {
        Debug.WriteLine("Test");

        ReportExecutionService rs = new ReportExecutionService();

        rs.Credentials = CredentialCache.DefaultCredentials;

        rs.Url = "http://localhost/reportserver/reportexecution2005.asmx";

        rs.ExecutionHeaderValue = new ExecutionHeader();
        var executionInfo = new ExecutionInfo();
        executionInfo = rs.LoadReport($"{ReportsDir}/Invoice/{report}", null);
        

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

        parameters.Add(new ParameterValue { Name = "SOPNUMBER", Value = invoice });
        parameters.Add(new ParameterValue { Name = "SOPTypeString", Value = "Invoice" });

        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);

        FileStream stream = File.Create(System.Web.HttpRuntime.CodegenDir + $"/{invoice}.pdf", result.Length);

        //write file with rendered result

        stream.Write(result, 0, result.Length);

        //close stream

        stream.Close();

        StorageFile file = StorageFile.GetFileFromPathAsync(System.Web.HttpRuntime.CodegenDir + $"/{invoice}.pdf").GetResults();

        var pdf = PdfDocument.LoadFromFileAsync(file).GetResults();

        return Ok(pdf);

    }
    catch (Exception ex)
    {
        Log.Logger.Error(ex, "Reporting Error");
    }

    return Ok();
}

This solved my problem.

Related