Wednesday, January 21, 2009

Integrating Reporting Services 2008 with SharePoint 2007 Step 1 - SQL Server 2008 Installation

Step 1 - SQL Server 2008 Installation and Configuration

Introduction

This post is the first of a group showing how to use SQL Server 2008 Reporting Services with SharePoint 2007.
The next steps are: I have chosen a Simple Farm Topology with SQL Server 2008 and Windows SharePoint Services 3.0 on the same Virtual Machine. This machine has just Application Server role and not Domain Controller role, so the Service Accounts for both, SharePoint and SQL will be machine local accounts.
The goal is to quickly allow someone to create reports and to discover SharePoint Integrated Mode features: deployment, Web Parts dashboards, subscription, snapshotings, etc..
Even planning for further deployments in a Farm environment with several servers and Active Directory, it may be usefull to have been familiarized with involved products installation, configuration and use, by having tested it in a Simple Farm Topology with one computer and local accounts.

For the current step, you can refer to this MSDN article: How to: Install SQL Server 2008 (Setup)

This installation is compliant with both MOSS 2007 and Windows SharePoint Services.

1 - Prerequisites
  • Be sure to have Windows 2003 Server with SP2 before starting installation.
2 - Installation Overview
This installation includes the following steps:
  • Step 1: Launching Installation
  • Step 2: prerequisites Installation dialog box
  • Step 3: Net Framework 3.5 + SP1 Installation
  • Step 4: Windows Installer 4.5 Installation
  • Step 5: Launching a new installation of SQL Server 2008
  • Step 6: Passing System Configuration Checker
  • Step 7: Choosing a free SQL Version, or entering product key
  • Step 8: SQL Server prerequisites Installation Wizard
  • Step 9: Passing System Configuration Checker
  • Step 10: Selecting Installation features
  • Step 11: Instance Configuration Page
  • Step 12: Disk Space Requirements Page
  • Step 13: Server Configuration
  • Step 14: DataBase Engine Collation
  • Step 15: Database Engine Configuration - Account Provisioning page
  • Step 16: Reporting Services Configuration page
  • Step 17: Error and Usage Reporting
  • Step 18: Passing System Configuration Checker
  • Step 19: Ready to install page - Installation Progress
  • Step 20: Closing Installation
  • Step 21: Checking Installation: Opening SQL Server 2008 Management Studio
  • Step 22: Configure your new SQL Server installation


3 - Installation
3.1 Step 1: Launching Installation
Double click the "setup.exe" of your SQL Server 2008 installation media.



3.2 Step 2: prerequisites Installation dialog box
If the prerequisites Installation dialog box appears, click OK.



3.3 Step 3: Net Framework 3.5 + SP1 Installation
If the 3.5 SP1 installation dialog box appears, select the radio button to accept the .NET Framework 3.5 SP1 License Agreement. Click Install.
You may wait from 5 to 20 minutes depending on your system hardware configuration.







When installation of .NET Framework 3.5 SP1 is complete, click Exit.




3.4 Step 4: Windows Installer 4.5 Installation
Windows Installer 4.5 is also required, and might be installed by the Installation Wizard.

















If you are prompted to restart your computer, restart it, and then restart SQL Server 2008 setup.exe.



3.5 Step 5: Launching a new installation of SQL Server 2008
When the prerequisites are installed, the Installation Wizard will run the SQL Server Installation Center. To create a new installation of SQL Server 2008, click New Installation or Add Features to an Existing Installation.



3.6 Step 6: Passing System Configuration Checker
The System Configuration Checker will run a discovery operation on your computer. To continue, click OK. Setup log files are created for your installation. For more information, see How to: View SQL Server Setup Log Files.



3.7 Step 7: Choosing a free SQL Version, or entering product key
On the Product Key page, select an option button to indicate whether you are installing a free edition of SQL Server, or a production version of the product that has a PID key.



On the License Terms page, read the license agreement, and then select the check box to accept the license terms and conditions.



3.8 Step 8: SQL Server prerequisites Installation Wizard 2
The Installation Wizard will install SQL Server prerequisites if they are not already on the computer. These include the following:
  • .NET Framework 3.5 SP1
  • SQL Server Native Client
  • SQL Server Setup Support Files
To install prerequisites, click Install.



3.9 Step 9: Passing System Configuration Checker
The System Configuration Checker will verify the system state of your computer before Setup continues.



3.10 Step 10: Selecting Installation features
On the Feature Selection page, we have now to select the components for our installation. A description for each component group appears in the right pane after you select the feature name.



I provide some more information on the current choices:
  • Data Base Engine is obviously mandatory

  • Full text search
    I didn't check it because of SharePoint. SharePoint 2007 with SQL Server 2008 configuration doesn't need Full-Text Search feature anymore as it is well explained in MSDN blog:
    On the other hand, I plan to install in a further step, SQL Server 2008 database samples (Adventure works), and these samples installation requires Full-Text search feature to be activated.

  • Business Intelligence Development Studio aka BIDS
    This is essential regarding Reporting Services integration as it is THE tool that will allow you to create reports and deploy them in SharePoint. For a SQL Server 2008 installation without Reporting Services you can avoid installing this feature.

  • Management-Tools Complete
    This feature will install Microsoft SQL Server Management Studio
    If you don't need Reporting Services, you can avoid checking complete feature, but the complete one install elements that runs with Reporting Services as noticed in description that appears in the right pane after you select the feature name.
You can also specify a custom directory for shared components by using the field at the bottom of the Feature Selection page. To change the installation path for shared components, either update the path in the field at the bottom of the dialog box, or click Browse to move to an installation directory. The default installation path is C:\Program Files\Microsoft SQL Server\100\.

3.11 Step 11: Instance Configuration Page
On the Instance Configuration page, specify whether to install a default instance or a named instance. For a simple farm topology installation on ONE virtual machine, default instance will be enough.



3.12 Step 12: Disk Space Requirements Page
The Disk Space Requirements page calculates the required disk space for the features that you specify. Then it compares the required space to the available disk space. For more information, see Disk Cost Summary.



3.13 Step 13: Server Configuration
On the Server Configuration — Service Accounts page, specify login accounts for SQL Server services. For a simple farm topology installation on ONE virtual machine, I have chosen to use an unique service account that is the Virtual Machine Administrator.
I advise you to configure the SQL Server Agent Service in automatic mode, because it is used by Subscriptions of SQL Server Reporting Services 2008, and doing that, you will not need to start the service manually every time you restart your server.



3.14 Step 14: DataBase Engine Collation Configuration
The SQL Server database collation must be configured for case-insensitive, accent-sensitive, Kana-sensitive, and width-sensitive. This is to ensure file name uniqueness consistent with the Windows operating system as specified this technet article:


3.15 Step 15: Database Engine Configuration - Account Provisioning page
Choose Mixed mode as SharePoint propose in certain screens (Web Application Creation, Search Starting, etc.) to use SQL Authentication.
The two passwords to be typed are for the "sa" login.



3.16 Step 16: Reporting Services Configuration page
We have to select the third option because SharePoint is not installed yet on the virtual machine.



3.17 Step 17: Error and Usage Reporting
On the Error and Usage Reporting page, specify the information that you want to send to Microsoft that will help improve SQL Server. By default, options for error reporting and feature usage are enabled.



3.18 Step 18: Passing System Configuration Checker
The System Configuration Checker will run one more set of rules to validate your computer configuration with the SQL Server features that you have specified.



3.19 Step 19: Ready to install page - Installation Progress
The Ready to Install page shows a tree view of installation options that were specified during Setup. To continue, click Install.



You may wait from 5 to 20 minutes depending on your system hardware configuration.
During installation, the Installation Progress page provides status so that you can monitor installation progress as Setup continues.







3.20 Step 20: Closing Installation
After installation, the Complete page provides a link to the summary log file for the installation and other important notes. To complete the SQL Server installation process, click Close.



3.21 Step 21: Checking Installation: Opening SQL Server 2008 Management Studio
From your machine Start Menu navigate to open SQL Server 2008 Management Studio.



Connect to DataBase Engine



Check it opens properly and contains all usual features.



3.22 Step 22: Configure your new SQL Server installation
As specified in the previously referred article We have to configure SQL Server in order to prepare SharePoint installation. As there is a change in the 2008 version of the Configuration Manager, this is the current way to proceed:

On the Start menu, point to All Programs, point to Microsoft SQL Server 2008, point to Configuration Tools, and then click SQL Server Configuration Manager.



Use the SQL Server Network Configuration area to enable connection protocols as follows:
  • Named Pipes Enabled
  • TCP/IP Enabled




Your SQL Server 2008 installation for Reporting Services Integration with SharePoint 2007 is done.

Wednesday, December 10, 2008

Create a SharePoint AJAX-refreshable Web Part which wraps an ASP .NET Chart Control

Introduction

This tutorial includes the steps for making a SharePoint AJAX-refreshable Web Part which wraps an ASP .NET Chart Control.
This tutorial is the following of two previous ones:
  1. MOSS, How to...: Use Microsoft Chart Controls for .Net framework in a SharePoint web site
  2. MOSS, How to...: Use Microsoft ASP .NET Chart Control in a SharePoint Web Part
In this tutorial, we are going to put together three important ASP .NET compliant Microsoft features:
  • Windows SharePoint Services 3.0 Web parts
  • Microsoft ASP .NET Chart Control
  • Microsoft ASP .NET AJAX 3.5
Ajax integration with ASP .NET Chart Control will be easier than ever since we already had to use the .Net Framework 3.5 for the ASP .NET Chart Control, and that the most significant advance in ASP .NET with .NET Framework 3.5 is improved support for the developement of AJAX-enabled web sites.
This tutorial is compliant with both MOSS 2007 and Windows SharePoint Services 3.0.



In this SharePoint Web part Page, 4 SharePoint Web Parts embedding an ASP .NET Chart Control can be refreshed independently some of the others using ASP .NET AJAX 3.5 and can be used to build a SharePoint Dashboard.

1 - Prerequisites

2 - Important ASP .NET AJAX 3.5 information:

1 - Using UpdatePanel control and efficiency.

There are roughly two ways of doing Ajax with Microsoft Ajax Framework.
  • Using UpdatePanel control
  • Using a web Service. ( ASMX Web method called through the javaScript Proxy).
Using UpdatePanel control while adding AJAX functionality to an aspx page DOES NOT increase performances of the page since when UpdatePanel control performs an asynchronous AJAX callback to the server to update its content, the request contains everything a conventional ASP .NET postback contains, including view state.
Unfortunatly, as an ASP .NET Chart Control is a Server Conrol, the only (easy) way of adding AJAX improvements to an .aspx page regarding an ASP .NET Chart Control is to use Update Panel. Of course Best Practices in using UpdatePanel can increase the page efficiency.

For more information there is this article of Jeff Prosise in MSDN Magazine (june 2007 issue)

2 - URL of the hosting SharePoint Web site

An article of Microsoft Knowledge Base reports that issue may occur if you use international characters in an URL of a SharePoint Page that contains a Web Part with ASP .NET AJAX Functionality. It is possible that this bug doesn't exist anymore with the ASP .NET AJAX 3.5 version.
For more information:

3 - Tutorial Overview

This tutorial includes the following steps:
  • Step 1: Configure your SharePoint environment for ASP .NET Ajax 3.5
  • Step 2: Create a new Class in AspNetChartControl.SharePointWebParts project
  • Step 3: Give the Class the Basic Structure for a SharePoint Web Part without forgetting the "public" class declaration.
  • Step 4: Define the Logic and rendering of your Web Part
  • Step 5: Implement Ajax functionality
  • Step 6: Build your web part
  • Step 7: Update the DLL already present in the web Application Bin Directory
  • Step 8: Import the site template default.aspx page in Visual Studio and rename it
  • Step 9: Add a Script Manager to the Web Part Page defaultWithScriptManager.aspx
  • Step 10: Add new Web Part Zones to the Web Part Page defaultWithScriptManager.aspx
  • Step 11: Import the Web Part Page defaultWithScriptManager.aspx into your Sharepoint Web Site.
  • Step 12: Import several Web Parts AjaxRefreshableChartWebPart into your Web Part Page.

4 - Tutorial

4.1 - Step 1: Configure your SharePoint environment for ASP .NET Ajax 3.5

We are going to add entries in the web.config file of the Web Application where is running the SharePoint Team site that is planned to welcome the Ajax-Refreshable Web part.
There is several way to modify this file in order to add support for .Net 3.5 in the SharePoint Web Application:
And the manual way that I have chosen to show here in its minimal version, in order to modify the web.config as little as possible since we have modified it yet for supporting ASP .NET Chart Control, and we have to use caution when modifying a Web Application web.config that is already complex enough.
Here are the steps (I have mentionned all of them ordered as in a SharePoint web.config file, but also mentionned the fact I have skipped some):
  • <config section> (skipped)
  • <SafeControls>
  • <httpHandlers>
  • <httpModules>
  • <assemblies>
  • <controls>
  • <system.web.extension> (skipped)
  • <system.web.server> (skipped)

  • <SafeControls>
    <!-- start adding -->
          <SafeControl Assembly="System.Web.Extensions, version=3.5.0.0, culture=Neutral, publicKeyToken=31bf3856ad364e35" Namespace ="System.Web.UI" TypeName="*" Safe="True" />
    <!-- end adding -->
    </SafeControls>
    
  • <httpHandlers>
          <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
          <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
          <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false" />
    
  • <httpModules>
          <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  • <assemblies>
            <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> 
            <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
            <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> 
            <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> 
    
    
  • <controls>
          </tagMapping>
          <!-- start adding -->
          <controls>
            <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add tagPrefix="asp" namespace="System.Web.UI.DataVisualization.Charting" assembly="System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
          </controls>
          <!-- end adding -->
        </pages>
    

4.2 - Step 2: Create a new Class in AspNetChartControl.SharePointWebParts project

To create a new class
  1. Right click your project in the Solution Explorer
  2. Select Add in the first menu
  3. Select Class in the second menu
  4. In the opening Dialog type the new Class name: AjaxRefreshableWebPart.cs
  5. Click Add.





This is the code state at the end of this step:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AspNetChartControl.SharePointWebParts
{
    class AjaxRefreshableWebPart
    {
    }
}

4.3 - Step 3: Give the Class the Basic Structure for a SharePoint Web Part without forgetting the "public" class declaration.

Refering to previous tutorial from 3.2 to 3.5, give the Class the basic structure for a Sharepoint Web part Class.
This is the code state at the end of this step:
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Web.UI.DataVisualization.Charting;
using System.Xml;
using System.Diagnostics;

namespace AspNetChartControl.SharePointWebParts
{
    [ToolboxData("<{0}:AjaxRefreshableWebPart runat=server></{0}:AjaxRefreshableWebPart>")]
    public class AjaxRefreshableWebPart : Microsoft.SharePoint.WebPartPages.WebPart
    {


        protected override void CreateChildControls()
        {
            base.CreateChildControls();
        }

        protected override void RenderWebPart(HtmlTextWriter output)
        {
            base.RenderWebPart(output);
        }
    }
}

4.4 - Step 4: Define the Logic and rendering of your Web Part

We are now using again one of the ASP .NET Chart Control Sample. In one of these samples (Stacked Charts), there is a piece of C# code that shows how to generate a random Chart Serie for a Chart Control. As we have not yet bound our Chart Control to a Data Source, we will use this random Chart Serie generation to simulate a real Data Source binding.



We have also to implement an ASP LinkButton to give user the chance to refresh the Web Part using it.
At the end of this step, we have a perfectly well working Wep Part, but it has not yet AJAX ability. That is to mean, if we build this code and deploy the Web Part, the click on the LinkButton will trigger a visible Postback of the Web Part Page.
This is the code state at the end of this step:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Web.UI.DataVisualization.Charting;
using System.Xml;
using System.Diagnostics;

namespace AspNetChartControl.SharePointWebParts
{
    [ToolboxData("<{0}:AjaxRefreshableWebPart runat=server></{0}:AjaxRefreshableWebPart>")]
    public class AjaxRefreshableWebPart : Microsoft.SharePoint.WebPartPages.WebPart
    {

        System.Web.UI.DataVisualization.Charting.Chart Chart1;
        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            LinkButton button1 = new LinkButton();
            button1.ID = "lButton1";
            button1.Text = "Refresh";
            button1.Click += new EventHandler(lButton_Click);

            Chart1 = new System.Web.UI.DataVisualization.Charting.Chart();

            Chart1.Width = 412;
            Chart1.Height = 296;
            Chart1.RenderType = RenderType.ImageTag;
            string imagespath = System.Configuration.ConfigurationSettings.AppSettings["ChartImageHandler"].ToString();
            Chart1.ImageLocation = imagespath + "ChartPic_#SEQ(200,30)";

            Chart1.Palette = ChartColorPalette.BrightPastel;
            Title t = new Title("Ajax-Refreshable ASP.NET Chart Control Web Part", Docking.Top, new System.Drawing.Font("Trebuchet MS", 14, System.Drawing.FontStyle.Bold), System.Drawing.Color.FromArgb(26, 59, 105));
            Chart1.Titles.Add(t);

            Chart1.BorderSkin.SkinStyle = BorderSkinStyle.Emboss;
            Chart1.BorderColor = System.Drawing.Color.FromArgb(26, 59, 105);
            Chart1.BorderlineDashStyle = ChartDashStyle.Solid;
            Chart1.BorderWidth = 2;

            if (Chart1.Series.FindByName("Series1") == null)
            {
                Chart1.Series.Add(new Series("Series1"));
                Chart1.ChartAreas.Add("Series1");
            }

            Random random = new Random();

            for (int pointIndex = 0; pointIndex < 10; pointIndex++)
            {
                Chart1.Series["Series1"].Points.AddY(random.Next(45, 95));
            }

            this.Controls.Add(Chart1);
            this.Controls.Add(button1);
        }

        void lButton_Click(object sender, EventArgs e)
        {
            Random random = new Random();

            for (int pointIndex = 0; pointIndex < 10; pointIndex++)
            {
                Chart1.Series["Series1"].Points.AddY(random.Next(45, 95));
            }
        }

        protected override void RenderWebPart(HtmlTextWriter output)
        {
            base.RenderWebPart(output);
        }
    }
}

4.5 - Step 5: Implement Ajax functionality

We are now going to give the Web Part its AJAX ability to be refreshed without triggering a visible Post Back. We know now that unfortunatly for the Page efficiency, UpdatePanel control trigger a PostBack, even if it is no visible.
For people that does not know at all how to use an UpdatePanel control, let's show the declarative syntax for that control that is very simple.
To use an UpdatePanel control in an ASP .NET Page and to give a piece of code the AJAX ability you just have to write that:
    <asp:ScriptManager ID="ScriptManager1" EnablePartialRendering="true" runat="server">
    </asp:ScriptManager>
        <asp:UpdatePanel ID="UpdatePanel1"  runat="server">
           <ContentTemplate>
              <!-- Place your code here -->
           </ContentTemplate>
        </asp:UpdatePanel>

Here is the previous code decorated with the implementation of the AJAX feature using the imperative syntax:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Web.UI.DataVisualization.Charting;
using System.Xml;
using System.Diagnostics;

namespace AspNetChartControl.SharePointWebParts
{
    [ToolboxData("<{0}:AjaxRefreshableWebPart runat=server></{0}:AjaxRefreshableWebPart>")]
    public class AjaxRefreshableWebPart : Microsoft.SharePoint.WebPartPages.WebPart
    {

        System.Web.UI.DataVisualization.Charting.Chart Chart1;
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            
            //UpdatePanel declaration, instantiation and identification
            UpdatePanel updatePanel1 = new UpdatePanel();
            updatePanel1.ID = "udpAjaxRefreshableChartControlWebPart";
            //the way the of refreshing
            updatePanel1.UpdateMode = UpdatePanelUpdateMode.Conditional;

            LinkButton button1 = new LinkButton();
            button1.ID = "lButton1";
            button1.Text = "Refresh";
            button1.Click += new EventHandler(lButton_Click);

            Chart1 = new System.Web.UI.DataVisualization.Charting.Chart();

            Chart1.Width = 412;
            Chart1.Height = 296;
            Chart1.RenderType = RenderType.ImageTag;
            string imagespath = System.Configuration.ConfigurationSettings.AppSettings["ChartImageHandler"].ToString();
            Chart1.ImageLocation = imagespath + "ChartPic_#SEQ(200,30)";

            Chart1.Palette = ChartColorPalette.BrightPastel;
            Title t = new Title("Ajax-Refreshable ASP.Net Chart Control Web Part", Docking.Top, new System.Drawing.Font("Trebuchet MS", 14, System.Drawing.FontStyle.Bold), System.Drawing.Color.FromArgb(26, 59, 105));
            Chart1.Titles.Add(t);

            Chart1.BorderSkin.SkinStyle = BorderSkinStyle.Emboss;
            Chart1.BorderColor = System.Drawing.Color.FromArgb(26, 59, 105);
            Chart1.BorderlineDashStyle = ChartDashStyle.Solid;
            Chart1.BorderWidth = 2;

            if (Chart1.Series.FindByName("Series1") == null)
            {
                Chart1.Series.Add(new Series("Series1"));
                Chart1.ChartAreas.Add("Series 1");

            }

            Random random = new Random();
            Debug.WriteLine("AjaxRefreshWebPart - CreateChildControls");


            for (int pointIndex = 0; pointIndex < 10; pointIndex++)
            {
                Chart1.Series["Series1"].Points.AddY(random.Next(45, 95));
            }

            //the controls are embedded inside the UpdatePanelControl
            updatePanel1.ContentTemplateContainer.Controls.Add(Chart1);
            updatePanel1.ContentTemplateContainer.Controls.Add(button1);

            this.Controls.Add(updatePanel1);
        }

        void lButton_Click(object sender, EventArgs e)
        {
            Random random = new Random();

            for (int pointIndex = 0; pointIndex < 10; pointIndex++)
            {
                Chart1.Series["Series1"].Points.AddY(random.Next(45, 95));
            }
        }

        protected override void RenderWebPart(HtmlTextWriter output)
        {
            base.RenderWebPart(output);
        }
    }
}

4.6 - Step 6 : Build your web part

After you add all of the preceding code, you can build your sample Web Part.

To build your Web Part
On the Build menu, click Build Solution.

4.7 - Step 7: Update the DLL already present in the web Application Bin Directory

After the Web Part is built, you must copy the resulting DLL to the bin directory. To copy your DLL to the bin directory

  1. On the file system, locate the AspNetChartControl.SharePointWebparts.dll file. It should be in
    C:\AspNetChartControl.SharePointWebparts\AspNetChartControl.SharePointWebparts\bin\Debug.
  2. Replace the AspNetChartControl.SharePointWebParts.dll in the the Web application root bin directory with the file from the output directory.

4.8 - Step 8: Import the site template default.aspx page in Visual Studio and rename it

Navigate to the following directory
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates\sts
Copy the default.aspx page and paste it in your project directory.
In the Visual Studio Solution Explorer click Display All Files button to make the default.aspx page to be visible.
Right click the page and click on "Include In Project".
Rename the page in "defaultWithScriptManager.aspx"



4.9 - Step 9: Add a Script Manager to the Web Part Page defaultWithScriptManager.aspx

open the Page in Code view
Expand Visual Studio Toolbox and locate the ScriptManager control and drag it.



Locate the first WepPartZone declaration and drop a ScriptManager instance upon it.




4.10 - Step 10: Add new Web Part Zones to the Web Part Page defaultWithScriptManager.aspx

Locate the HTML <tr> line that contains the 2 webPartZone and duplicate it.



Rename the 4 WebPartZones in order to obtain the following HTML code:
         <table width="100%" cellpadding=0 cellspacing=0 style="padding: 5px 10px 10px 10px;">
          <tr>
           <td valign="top" width="70%">
               <asp:ScriptManager ID="ScriptManager1" runat="server">
               </asp:ScriptManager>
               <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="LeftUp" Title="loc:LeftUp" />
               &nbsp;
           </td>
           <td>&nbsp;</td>
           <td valign="top" width="30%">
               <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="RightUp" Title="loc:RightUp" />
               &nbsp;
           </td>
           <td>&nbsp;</td>
          </tr>
                    <tr>
           <td valign="top" width="70%">
               <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="LeftDown" Title="loc:LeftDown" />
               &nbsp;
           </td>
           <td>&nbsp;</td>
           <td valign="top" width="30%">
               <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="RightDown" Title="loc:RightDown" />
               &nbsp;
           </td>
           <td>&nbsp;</td>
          </tr>
         </table>
When the changes are done, save the page.

4.11 - Step 11: Import the Web Part Page defaultWithScriptManager.aspx into your Sharepoint Web Site.

Go to the Shared Documents document library of your team site and select upload a document.


Then navigate to your project directory and choose the defaultWithScriptManager.aspx page.





4.12 - Step 12: Import several Web Parts AjaxRefreshableWebPart into your Web Part page.

Now you can add 4 AjaxRefeshableChartControlWebParts in your Page.



And notice that you can rename them, and they can be refreshed independently some of the others using ASP .NET AJAX 3.5 and can be used to build a SharePoint Dashboard.



5 - For more information

You can find additional information at: I plan writing soon a post on Data Binding for these Web Parts, and a more generic article on dashboards with WSS 3.0.
By the way, there will be an interesting conference on that topic in february:
Case Studies in SharePoint Dashboards - The Sequel
If you are planning to realize such dashboards using ASP .NET Chart Controls, I will be pleased to exchange information with you...

Thursday, December 4, 2008

Use a Microsoft Asp .Net Chart Control in a SharePoint Web Part

Introduction

This tutorial includes the steps for creating a basic custom Windows SharePoint Services Web Part which wraps a Microsoft Chart Control for ASP .Net. It is a simple Web Part that allows you to change the Enabled property of the ASP .Net Chart control's legend. The System.Web.UI.DataVisualization.Charting.Legend class is used to manage the legend of the Asp .Net Chart.
The goal of this tutorial was to place inside a Web Part the "Chart without Code-Behind" sample, that is one of the 200 Interactive Samples for Asp .Net Chart Control from Samples Environment for Microsoft Chart Controls .



This also, shows how to develop quickly : test your solution in "in line" script, then, deploy it using a component, as I wrote before in This tutorial is compliant with both MOSS 2007 and Windows SharePoint Services.

Beginning with Windows SharePoint Services 3.0, the Windows SharePoint Services Web Part infrastructure is built on top of the Microsoft ASP.NET 2.0 Web Part infrastructure and Web Parts that derive from the ASP.NET WebPart class are completely supported in Windows SharePoint Services. You should create ASP.NET Web Parts whenever possible.
For more information about choosing the best Web Part base class from which to derive, see Developing Web Parts in Windows SharePoint Services in the Windows SharePoint Services Software Development Kit (SDK). For more information about ASP.NET Web Parts, see the Web Parts Control Set Overview in the ASP.NET documentation.

To see a much more complete example of a Web Part wrapping an ASP .net Chart Control, you can go to CodePlex and examine the Wictor Wilén's ChartPart derive from ASP .Net WebPart class. The one of this tutorial derive from Windows SharePoint Services Web Part Class.

1 - Prerequisites

  • Usual development environment for SharePoint (Windows 2003 Server or Windows Server 2008 with a SharePoint installation).
  • Microsoft Chart Controls for Microsoft .NET Framework 3.5 are installed on the development environment. You can download installation package here
  • Microsoft Visual Studio 2008 is installed on the development environment.
  • Microsoft Chart Controls Add-on for Microsoft Visual Studio 2008 is installed on the development environment.
  • Samples Environment for Microsoft Asp .Net Chart Controls is installed on the development environment.
  • Your SharePoint environement is properly configured for ASP .Net Chart Controls. If you are not sure you can check the configuration in my previous post, sections 3.3 and 3.4, or do this previous post quick tutorial in order to validate your environment by displaying the Chart Control Sample on a SharePoint page.
  • You have a SharePoint team site ready to welcome the Asp .Net Chart control Web part.

2 - Tutorial Overview

This tutorial includes the following steps:
  • Step 1: Create an ASP .Net Server Control project
  • Step 2: Add a reference to Microsoft.SharePoint.dll, System.Web.DataVisualization.dll and regarding Namespace Directives
  • Step 3: Rename the Class
  • Step 4: Inherit from the Web part Class
  • Step 5: Use the RenderWebpartMethod
  • Step 6: Define the Logic and rendering of your Web Part using Asp .Net Chart Control Samples and the CreateChildControls Method
  • Step 7: Build your web part
  • Step 8: Copy your DLL to the Bin Directory
  • Step 9: Add ControlSafe Entry in the Web Application web.config
  • Step 10: Import the site template default.aspx page and use it as a Web Part page
  • Step 11: Import the ASP .Net Chart Control Web Part into your Web Part page.
Warning: I skipped some steps in order to give a quick result. To be really compliant with the SharePoint Web Part development best practices refer to:

3 - Tutorial

3.1 Step 1: Create an ASP .Net Server Control project
To create a new ASP .Net Server Control project
  1. Start Visual Studio 2008.
  2. On the File menu, point to New, and then click Project.
  3. In the New Project dialog box, click Visual C# Projects or Visual Basic Projects, and then select the ASP .Net Server Control project template.
  4. Type AspNetChartControl.SharePointWebParts as the name and specify the location for the project files, and then click OK.




3.2 Step 2: Add a reference to Microsoft.SharePoint.dll, System.Web.DataVisualization.dll and regarding Namespace Directives
To create a Web Part, you need to add a reference to the Microsoft.SharePoint assembly (Microsoft.SharePoint.dll) in your Web Control Library project.
To add a reference to Microsoft.SharePoint.dll
  1. On the Project menu, click Add Reference.
  2. On the .NET tab, double-click Windows SharePoint Services.
  3. Click OK.



To make it easier to write a basic WebPart class, you should use the using directive in C# or the Imports directive in Visual Basic to reference the following namespace in your code:
The Microsoft.SharePoint.WebPartPages namespace provides the types for Web Part pages, such as the Microsoft.SharePoint.WebPartPages.WebPart class.



As we are going to use a Microsoft Asp .Net Chart Control in our web part, we have to do exactly the same for the System.Web.DataVisualization.dll and regarding System.Web.UI.DataVisualization.Charting namespace.





3.3 Step 3: Rename the Class and clean up the code
To rename the class
  1. In the solution explorer right click the class file and select rename
  2. Rename the file in DynamicLegendWebPart (don't forget extension)
  3. Click ok on the message box that will ask you to rename the other instance of the clas name inside your source code.
Don't forget to rename the parameter of the ToolBoxData Attribute.
As we won't use any property for this web part, delete the "Text" property, the corresponding class attribute and the reference in the Render Content Method.



This is the code state at the end of this step:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.WebPartPages;

namespace AspNetChartControl.SharePointWebParts
{
    [ToolboxData("<{0}:DynamicLegendWebPart runat=server></{0}:DynamicLegendWebPart>")]
    public class DynamicLegendWebPart : WebControl
    {


        protected override void RenderContents(HtmlTextWriter output)
        {

        }
    }
}
3.4 Step 4: Inherit from the Web part Class
By default, the Web Control Library template creates a custom control that inherits from the System.Web.UI.Control class (a parent class of both the ASP.NET and SharePoint WebPart classes).
To create a SharePoint Web Part, you should inherit from the Microsoft.SharePoint.WebPartPages.WebPart base class.

To inherit from the Web Part base class.

Replace this line of code:
public class DynamicLegendWebPart : WebControl 
with this line:
public class DynamicLegendWebPart : WebPart
This is the code state at the end of this step:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.WebPartPages;

namespace AspNetChartControl.SharePointWebParts
{
    [ToolboxData("<{0}:DynamicLegendWebPart runat=server></{0}:DynamicLegendWebPart>")]
    public class DynamicLegendWebPart : WebPart
    {


        protected override void RenderContents(HtmlTextWriter output)
        {

        }
    }
}

3.5 Step 5: Use the RenderWebpartMethod
The WebPart base class seals the Render method of System.Web.UI.Control because the Web Part infrastructure needs to control rendering the contents of a Web Part. For this reason, custom Web Parts must override the RenderWebPart method of the WebPart base class.
To use the RenderWebPart method.
Replace this line of code:

protected override void RenderContents(HtmlTextWriter output)
with this line:
protected override void   RenderWebPart(HtmlTextWriter output)
3.6 Step 6: Define the Logic and rendering of your Web Part using Asp .Net Chart Control Samples and the CreateChildControls Method


After you complete the previous steps, you can define the logic and rendering for your Web Part. For this part, we will, as annouced previously, rewrite the in-line code of the "Chart Without Code Behind" Sample, in order to make this sample work inside a web part.



The steps are the following :
  1. Write a CreateChildControls Method to add the Asp .Net Chart Control and the CheckBox Control as child controls of the Web Part
  2. Inside this method:
    • add text and Autopostback to the CheckBox
    • Change the image location definition using our web.config AppSettings
    • Change the Chart Title
    • Add the controls as children
  3. Move the render instruction to the RenderWebPart Method
  4. Override OnLoad Method in order to see the changes after the PostBack
  5. Place the Legend Enabling instructions inside the OnLoad Method
  6. Move the declaration and instanciation instructions for the two child controls outside the methods in order to factorize them.


Here is the complete code before rewriting with the TODO instructions:
  <%
                        //put this at the top of the class to this to be shared by all the methods
                        System.Web.UI.DataVisualization.Charting.Chart Chart1 = new System.Web.UI.DataVisualization.Charting.Chart();
                        //declare and instantiate the checkBox control in the same place and way
                        
                        //All the following (untill next method instruction) go Inside CreateChildControls Method
                        //Set the text property value of the Checkbox control to "Show Legend"
                        //Set the AutoPostBack porperty value to true
                        
                        Chart1.Width = 412;
                        Chart1.Height = 296;
                        Chart1.RenderType = RenderType.ImageTag;
                        //Use the AppSettings to retrieve the path from our web.config
                        Chart1.ImageLocation = "..\\..\\TempImages\\ChartPic_#SEQ(200,30)";
                        
                        Chart1.Palette = ChartColorPalette.BrightPastel;
                        //Change the title to " Dynamic Legend SharePoint Web Part with ASP .net Chart Control"
                        Title t = new Title("No Code Behind Page", Docking.Top, new System.Drawing.Font("Trebuchet MS", 14, System.Drawing.FontStyle.Bold), System.Drawing.Color.FromArgb(26, 59, 105));
                        Chart1.Titles.Add(t);
                        Chart1.ChartAreas.Add("Series 1");
                        // create a couple of series
                        Chart1.Series.Add("Series 1");
                        Chart1.Series.Add("Series 2");
                        
                        
                        // add points to series 1
                        Chart1.Series["Series 1"].Points.AddY(5);
                        Chart1.Series["Series 1"].Points.AddY(8);
                        Chart1.Series["Series 1"].Points.AddY(12);
                        Chart1.Series["Series 1"].Points.AddY(6);
                        Chart1.Series["Series 1"].Points.AddY(9);
                        Chart1.Series["Series 1"].Points.AddY(4);
                         
                        // add points to series 2
                        Chart1.Series["Series 2"].Points.AddY(2);
                        Chart1.Series["Series 2"].Points.AddY(6);
                        Chart1.Series["Series 2"].Points.AddY(18);
                        Chart1.Series["Series 2"].Points.AddY(16);
                        Chart1.Series["Series 2"].Points.AddY(21);
                        Chart1.Series["Series 2"].Points.AddY(14);
                          
                        Chart1.BorderSkin.SkinStyle = BorderSkinStyle.Emboss;
                        Chart1.BorderColor = System.Drawing.Color.FromArgb(26, 59, 105);
                        Chart1.BorderlineDashStyle = ChartDashStyle.Solid;
                        Chart1.BorderWidth = 2;
                        
                        Chart1.Legends.Add("Legend1");
                        
                            // show legend based on check box value
                        //Put this in OnLoad Method 
                        Chart1.Legends["Legend1"].Enabled = ShowLegend.Checked;
                        //Put this in the RenderWebPart Method with the correct syntax
                        // Render chart control
                        Chart1.Page = this;
                        HtmlTextWriter writer = new HtmlTextWriter(Page.Response.Output);
                        Chart1.RenderControl(writer);
                    
                     %>
                     <!-- Make a child control of the web part with all the following -->
                    </td>
                    <td valign="top">
                        <table class="controls" cellpadding="4">
                            <tr>
                                <td class="label48"></td>
                                <td>
                                    <p><asp:checkbox id="ShowLegend" runat="server" Text="Show Legend" AutoPostBack="True"></asp:checkbox></p>
                                </td>
                            </tr>
                        </table>

Here is the complete code after rewriting: DynamicLegendWebpart.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Web.UI.DataVisualization.Charting;
namespace AspNetChartControl.SharePointWebParts
{
    [ToolboxData("<{0}:DynamicLegendWebPart runat=server></{0}:DynamicLegendWebPart>")]
    public class DynamicLegendWebPart : WebPart
    {
        System.Web.UI.DataVisualization.Charting.Chart Chart1 = new System.Web.UI.DataVisualization.Charting.Chart();
        CheckBox ShowLegend = new CheckBox();
        protected override void OnLoad(EventArgs e)
        {
            Chart1.Legends.Add("Legend1");
            Chart1.Legends["Legend1"].Enabled = ShowLegend.Checked;
        }
        protected override void CreateChildControls()
        {
            ShowLegend.AutoPostBack = true;
            ShowLegend.Text = "Show Legend ";
            Chart1.Width = 412;
            Chart1.Height = 296;
            Chart1.RenderType = RenderType.ImageTag;
            string imagespath = System.Configuration.ConfigurationSettings.AppSettings["ChartImageHandler"].ToString();
            Chart1.ImageLocation = imagespath + "ChartPic_#SEQ(200,30)";
            Chart1.Palette = ChartColorPalette.BrightPastel;
            Title t = new Title("Dynamic Legend Web Part with ASP .Net Chart Control", Docking.Top, new System.Drawing.Font("Trebuchet MS", 14, System.Drawing.FontStyle.Bold), System.Drawing.Color.FromArgb(26, 59, 105));
            Chart1.Titles.Add(t);
            Chart1.ChartAreas.Add("Series 1");
            // create a couple of series
            Chart1.Series.Add("Series 1");
            Chart1.Series.Add("Series 2");
            // add points to series 1
            Chart1.Series["Series 1"].Points.AddY(5);
            Chart1.Series["Series 1"].Points.AddY(8);
            Chart1.Series["Series 1"].Points.AddY(12);
            Chart1.Series["Series 1"].Points.AddY(6);
            Chart1.Series["Series 1"].Points.AddY(9);
            Chart1.Series["Series 1"].Points.AddY(4);
            // add points to series 2
            Chart1.Series["Series 2"].Points.AddY(2);
            Chart1.Series["Series 2"].Points.AddY(6);
            Chart1.Series["Series 2"].Points.AddY(18);
            Chart1.Series["Series 2"].Points.AddY(16);
            Chart1.Series["Series 2"].Points.AddY(21);
            Chart1.Series["Series 2"].Points.AddY(14);
            Chart1.BorderSkin.SkinStyle = BorderSkinStyle.Emboss;
            Chart1.BorderColor = System.Drawing.Color.FromArgb(26, 59, 105);
            Chart1.BorderlineDashStyle = ChartDashStyle.Solid;
            Chart1.BorderWidth = 2;
            this.Controls.Add(Chart1);
            this.Controls.Add(ShowLegend);
        }
        protected override void RenderWebPart(HtmlTextWriter output)
        {
            // Render chart control and checkBox
            RenderChildren(output);
        }
    }
}
3.7 Step 7: Build your web part
After you add all of the preceding code, you can build your sample Web Part.

To build your Web Part
On the Build menu, click Build Solution.
3.8 Step 8: Copy your DLL to the Bin Directory
After the Web Part is built, you must copy the resulting DLL to the bin directory. To copy your DLL to the bin directory
  1. On the file system, locate the AspNetChartControl.SharePointWebparts.dll file. It should be in
    C:\AspNetChartControl.SharePointWebparts\AspNetChartControl.SharePointWebparts\bin\Debug.
  2. Copy the AspNetChartControl.SharePointWebParts.dll file from the output directory to the Web application root bin directory. The default location of the Web application root for is C:\Inetpub\wwwroot\wss\VirtualDirectories\PortNumber\bin.




3.9 Step 9: Add ControlSafe Entry in the Web Application web.config
I skipped some steps required to be compliant with the best practices, for the demonstration to be quick. But you should usually:
  • compile the dll with a strong name and an AllowPartiallyTrustedCallers attribute
  • at least modify the trust level of the web.config and the best would be to use Code Access Security policies
.Anyway for a fast demonstration, with just adding the non-signed dll in the bin directory and this entry in the web.config, it works !
 <SafeControl Assembly="AspNetChartControl.SharePointWebParts" Namespace="AspNetChartControl.SharePointWebParts" TypeName="*" Safe="true" />
<SafeControls />
3.10 Step 10: Import the site template default.aspx page and use it as a Web Part page
I want now to show an amazing trick to have quickly a web Part Page with a master page, especially for people who just have WSS 3.0.
Go to the Shared Documents document library of your team site and select upload a document.



Then navigate to the following directory
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates\sts
and choose the default.aspx page.



You have now in the Shared Documents library a brand new Web Part Page with the Quick Launch menu !



3.11 Step 11: Import the ASP .Net Chart Control Web Part into your Web Part page.


To import your Web Part

Navigate to the site collection settings of your site, on the Site Settings page, click Web Parts under the Galleries heading.




In the Web Part Gallery, click New.
Locate and check AspNetChartControl.SharePointWebParts.DynamicLegendWebPart



Click on button Populate Gallery

The Web part is now available in the Web part gallery



Navigate back to the Web Part page. In the Web Part page, click Site Actions, and select Edit Page.

In your preferred zone, click Add a Web Part and check the box next to DynamicLegendWebPart in the dialog box. Click Add.





After the Web Part is added to the zone, check and uncheck the Show Legend CheckBox to test the Web Part.