Thứ Sáu, 18 tháng 6, 2010

Combine Microsoft ReportViewer, WCF and ASP.NET

Scenario:

- We have a existing Website portal using ASP.NET

- We have a reporting desktop application using Microsoft ReportViewer

- We want to share some report from reporting application to website portal

Solution:

- We use WCF as interface to integrated between ASP.NET and desktop applications

- WCF will provides reports as streaming images data.

Implementation:

Step 1: Create WCF Services

- Create new WCF Service Application from Visual Studio 2010

A21319952F68E79E_862_0[1]

- Define Service Contract

[ServiceContract]
public interface IService1
{
    [OperationContract]
    Stream GenerateImage();        
} 

- Implement Service Contract. We must to export LocalReport to image stream



public System.IO.Stream GenerateImage()
        {
            LocalReport report = new LocalReport();
            //string path = @"D:\Report1.rdlc";
            string path = HttpContext.Current.Server.MapPath("~/Report1.rdlc");
            report.ReportPath = path;
 
            Warning[] warnings;
            string[] streamids;
            string mimeType;
            string encoding;
            string extension;
 
            byte[] bytes = report.Render(
               "Image", null, out mimeType, out encoding,
                out extension,
               out streamids, out warnings);
            Stream stream = new MemoryStream(bytes);
            return stream;
        }

- Enable WCF Streaming in configuration file



<basicHttpBinding>
  <binding name="HttpStreaming" maxReceivedMessageSize="67108864"
           transferMode="Streamed"/>
</basicHttpBinding>

- Create a new Report1.rdlc as following:


A21319952F68E79E_862_1[1]


- Step 2: Test the Service on Windows Form:


- Create new Windows Forms


- Add services reference to your service


- Add a PictureBox control to Form interface then add following code in code behind



public Form1()
        {
            InitializeComponent();
            ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
            Stream memList = client.GenerateImage();           
           
            System.Drawing.Image image = System.Drawing.Image.FromStream(memList);                  
            pictureBox1.Image = image;
        }

- Run the Form you will see:


A21319952F68E79E_862_2[1]


- Step 3: Rendering Image to website portal


- Similar in Windows Form, ASP.NET can display image from stream by very simple code:



protected void Page_Load(object sender, EventArgs e)
        {
            ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
            Stream memList = client.GenerateImage();
         
            System.Drawing.Image image = System.Drawing.Image.FromStream(memList);
            image.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);            
        }

- You will see:


A21319952F68E79E_862_3[1]


Conclusion:


There are three technical used to resolve this scenario:


- Export ReportViewer to image stream


- Enable Streaming in WCF


- Rendering Image from streaming data.


Reference:


- How to: Enable Streaming


- LocalReport.Render Method (String, String, out String, out String, out String, out String[], out Warning[])