9

I've a reporting services server which has already some running reports, and I need now to generate them through a custom website(running asp.net MVC3).

I need to retrieve this report as stream/byte to send it to the user. No "report viewer" or so.

Last time I used reporting services was with sql 2005, and We should ad as reference an obscure asmx file.

What's about now, with sql server reporting 2008 R2, .Net4 and visual studio 2010? I can't find a tutorial explaining the whole thing.

(in fact I can't find a tutorial where there is no report viewer for sql 2008 r2)

Ryan Erickson
  • 731
  • 1
  • 15
  • 23
J4N
  • 19,480
  • 39
  • 187
  • 340
  • 1
    I think you're talking about accessing SSRS through the web service API. What exactly is *obscure* about that web service? – Yuck Jun 05 '12 at 14:15

2 Answers2

18

Several methods are provided at MSDN. I have used URL access often for quick simple PDF buttons in an ASP .NET app.

Here's a quick hack bit of code doing this. It could be cleaned up to use integrated authentication, and there are many ways you could store the report name. (I cut and pasted this from some old code I had that would store a report to a database and then later could return that from the db.

// First read in the report into memory.

string strReportUser = "RSUserName";
string strReportUserPW = "MySecretPassword";
string strReportUserDomain = "DomainName";

string sTargetURL = "http://SqlServer/ReportServer?" +
   "/MyReportFolder/Report1&rs:Command=Render&rs:format=PDF&ReportParam=" +
   ParamValue;

HttpWebRequest req =
      (HttpWebRequest)WebRequest.Create( sTargetURL );
req.PreAuthenticate = true;
req.Credentials = new System.Net.NetworkCredential(
    strReportUser,
    strReportUserPW,
    strReportUserDomain );

HttpWebResponse HttpWResp = (HttpWebResponse)req.GetResponse();

Stream fStream = HttpWResp.GetResponseStream();




//Now turn around and send this as the response..
byte[] fileBytes = ReadFully( fStream );
// Could save to a database or file here as well.

Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader(
    "content-disposition",
    "attachment; filename=\"Report For " +
        ParamValue + ".pdf\"" );
Response.BinaryWrite( fileBytes );
Response.Flush();
HttpWResp.Close();
Response.End();

ReadFully is

public static byte[] ReadFully( Stream input )
{
   using ( MemoryStream ms = new MemoryStream() )
   {
      input.CopyTo( ms );
      return ms.ToArray();
   }
}  
Jamie F
  • 23,189
  • 5
  • 61
  • 77
  • But, how to manage the identification? Because all users should not have access to the reporting services, no? – J4N Jun 05 '12 at 18:17
  • Could you just point me to the right class/exemple to get the report from SSRS from the URL? I must admit that I don't know how to access to the url, specifying credentials and downloading the report. Thank you very much! – J4N Jun 06 '12 at 08:09
  • Not sure what you're looking for. The URL access link I posted above has three examples of different URLs that can be used to access reports. The details of how to do this depend on your report: what parameters do you use, how will you get your credentials. I've added some sample C# code to my answer. But if you want better examples, please let us know exactly what part you are having difficulty with. – Jamie F Jun 06 '12 at 15:02
  • can you help here please? http://stackoverflow.com/questions/10917941/how-to-exclude-column-from-a-report – Alex Gordon Jun 06 '12 at 16:08
  • Thanks Jamie, it was exactly what I needed. I didn't know how to receive the data. I was only wondering if I can give to the HttpWebRequest the stream in which it will write the response stream? – J4N Jun 06 '12 at 19:26
  • I believe you need to copy from one to the other: there are a few ways to do this, such as http://stackoverflow.com/questions/230128/best-way-to-copy-between-two-stream-instances-c-sharp – Jamie F Jun 06 '12 at 19:30
  • I'm getting an Error - "Cannot access closed Stream" – Riaan Dec 07 '14 at 07:11
  • Response says 'The name 'Response' does not exist in the current context... I have System.Web and still nothing, any tips? – Crezzer7 May 07 '15 at 07:30
0

Because you have nested streams, you may want to close the first stream after the copy to avoid a closed stream error. Also, if you get a 401 Unauthorized, try default credentials.

            req.UseDefaultCredentials = true;
            req.PreAuthenticate = true;
            req.Credentials = CredentialCache.DefaultCredentials;

            HttpWebResponse HttpWResp = (HttpWebResponse)req.GetResponse();

            Stream fStream = HttpWResp.GetResponseStream();                

            //Now turn around and send this as the response..
            byte[] fileBytes = ReadFully(fStream);
            // Could save to a database or file here as well.
            HttpWResp.Close();
Marius
  • 85
  • 9