Developer Zone
Register  |  Login  
 Mainsoft.com
Search  
 

Creating WebSphere Portal Apps Using the Visual Studio IDE

Overview

Unlike remoting solutions based on Web Services for Remote Portlets (WSRP), Mainsoft®, Portal Edition, enables you to use your expertise in Visual Studio® development and the C#/Visual Basic languages to create portlets that run natively on IBM WebSphere® Portal and integrate tightly with the Java stack of the portal server itself.

A comparison between WSRP vs Mainsoft is fully discussed in a Java Developer's Journal article written by Laurence Moroney on approaches to integrating .NET and Java components within WebSphere Portal.

In this article, we’ll show you how to create a fully featured ASP.NET portfolio portlet that runs locally on IBM WebSphere Portal as a JSR 168 compliant portlet. Your C# portlet will have direct access to IBM's rich set of end-user features, including single sign-on, people awareness, branding, and inter-portlet communications. At the end of the day, end users won’t know whether the portlets were created in C#, Visual Basic, or Java, because they behave exactly the same within the portal environment.

You can find the code for the sample ASP.NET portlet when you install Mainsoft, Portal Edition, at: <Mainsoft_install_dir>\Samples\{CS|VB}\WebSpherePortal\ASPNETFolio.

Getting started

Figure 1. Configuring the IDE for WebSphere Portal server.

Figure 2. Creating a new portal application.

Before we begin, set up an environment with WebSphere Portal 6.0, the Visual Studio development environment, and Mainsoft, Portal Edition, installed. Check the system requirements for details.

Then, in the Visual Studio IDE, add WebSphere Portal as a target server for portlet development. You do this using the Tools > Options menu, and then selecting Mainsoft for Java EE. If WebSphere Portal is not on the list, click the Add button to add it. You can see this dialog in Figure 1.

Now you are ready to create a new portal application using the Visual Studio New Project wizard (see Figure 2).

The project contains the necessary files to build and run your portal application. In this example, the application is a simple portfolio manager that updates stock prices based on a publicly available Web service.

In addition to seeing all your familiar files for .NET development, including Default.aspx, - that we renamed in this sample to ViewForm.aspx - and Web.config, you'll also find a few new files that are required by the JSR 168 specifications to deploy your portlet application on WebSphere Portal. You'll see a META-INF directory that contains the application manifest, a file used to describe your application to the portal server, and a WEB-INF directory that contains the deployment descriptor files used by the portal server at deployment time. You'll be editing some of these files a little later.

Creating the Web reference

Figure 3. Adding a Web reference.

To create the Web reference, right-click References in the Solution Explorer and select Add Web Reference. You'll see the Add Web Reference dialog (Figure 3) into which you need to enter the URL: http://www.webservicex.net/stockquote.asmx?wsdl. When you are done, select Add Reference and the Visual Studio IDE will create the Web service proxy for you.

Using WebSphere Portal theme

Next, we’ll brand the ASP.NET server controls automatically using WebSphere Portal themes. The ASP.NET controls style elements inherit the stylesheet elements of the Portal theme (e.g. fonts, colors, table styles, etc.) using the ASP.NET WebSphere Portal theme file that is part of Mainsoft Portal Application template.

Figure 4. WebSphere Portal theme that binds the ASP.NET controls to the appropriate stylesheet classes WebSphere Portal.

Figure 4 shows the WebSphere Portal theme that is part of every portal application you develop using Mainsoft.

Step 1. Creating the Data Grid and binding it to the portfolio data

Let’s create a data grid that displays portfolio information that is retrieved through an object data source from an XML file.

First, create the XML file by adding new XML file called portfolios.xml to your project. Fill out this file with the XML from Listing 1.

Next, create a data source that will load the information from the XML file. Add a new class file named portfolio.cs. You can find the code for portfolio.cs in Listing 2.

Change the code to match the namespace of your Web reference:

using ASPNETFolio.net.webservicex.www;
							

In portfolio.cs, the following function will be used by the ObjectDataSource control to get the data:

public DataSet GetPortfolioData(String exchange)
							

Now, create an ObjectDataSource that will fetch the data from the Portfolio object (through the GetPotfolioData method) and bind it to a GridView. Open the ViewForm.aspx designer, drop an ObjectDataSource ASP.NET control on it, and set the following properties:

Figure 5. Running the basic portfolio application locally in WebSphere Portal.

  • TypeName: ASPNETFolio.Portfolio -- This is the data source object.
  • SelectMethod: GetPortfolioData -- This is the method that returns the DataSet.
  • SelectParameters: Add a new Parameter named "Exchange" with the following settings:
    • Parameter source: ProfileParameter // This will fetch only the tickers from the NASDAQ exchange
    • PropertyName: Exchange
    • DefaultValue: NASDAQ

If you switch the source view of ViewForm.aspx, your ObjectDataSource control should look like this:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="GetPortfolioData" TypeName="ASPNETFolio.Portfolio">
      <SelectParameters>
      <asp:ProfileParameter DefaultValue="NASDAQ" Name="Exchange"
      PropertyName="Exchange" />
      </SelectParameters>
</asp:ObjectDataSource>
							

Finally, drop a GridView ASP.NET control on ViewForm.aspx and set its DataSourceID property to match the ID of the ObjectDataSource you just created (e.g. ObjectDataSource1).

When you run the application, you’ll see the results in Figure 5.

Step 2. Making the grid visually pleasing – using C#

Figure 6. The GridView property builder.

Figure 7. Enhancing the grid using your existing ASP.NET skills.

The column names in Figure 5 are not intuitive because GridView gets its column names from the field names by default. So we’ll use the ASP.NET GridView control to create BoundColumn settings, filter out unwanted fields, and enter user-friendly text on the column header rather than the data column name.

Go to the property builder by selecting the columns property of the GridView control. If you are familiar with configuring standard ASP.NET GridView properties, this dialog box will look very familiar to you. In fact, it is the same property builder you use whenever you develop ASP.NET projects for Windows (see Figure 6.)

Make sure that the Auto-generate fields checkbox is not selected, and create new Bound Columns for each field you want to render at runtime. For each of these columns, enter a Header text entry to set the header text and a Data Field entry to indicate the data item. So, if you want the column called Ticker to have the header Ticker or Stock Ticker, enter the text as shown. Then, run the application again, and you will see the new Column Headings. You can also use the Data Formatting Expression field to enter a data formatting command code. Since we are using currency values, the value to enter here for the monetary fields is ${0:C}. See Figure 7 for the results.

Now the grid looks presentable, thanks to your expertise in .NET development and ASP.NET!

Accessing user profile information

User customization is an important part of every Web application that serves authenticated users. Microsoft created the ASP.NET Profile APIs with its built-in storage to make it easier to manage and store user profile data. Mainsoft extends these capabilities to the Java EE portal, mapping .NET Profile APIs to the portal user profile management.

In the sample, we fetch profile information from the logged-in portal user using ASP.NET Profile API. Let’s see how this mapping works.

Mainsoft’s portal application template generates a web.config file that configures the Mainsoft WebSphere specialized profile:

<profile enabled="true" defaultProvider="WPProfileProvider"
inherits="Mainsoft.Web.Profile.WPUserProfile">
						

Then, we can use the Mainsoft Profile namespace that defines the WPUserProfile base profile class in ViewForm.aspx.cs:

using Mainsoft.Web.Profile;
						

Now, we can access the namespace in the page_load of ViewForm.aspx:

// Fetch the Portal user profile information 
// through ASP.NET Profile,
// WP Profile inherits from WPUserProfile that is
// initialized with Portal user profile information
WPUserProfile WPProfile = (WPUserProfile) Context.Profile;
// WPUserProfile properties match JSR168 user properties
String GivenName = WPProfile.user.name.given;
String FamilyName = WPProfile.user.name.family;
String Email = WPProfile.user.business_info.online.email;
						

Figure 8. The portlet.xml designer.

Figure 9. Selecting the JSR 168 user profile attributes that we would like to access

The WPUserProfile properties are derived from the JSR 168 specifications, which define the user attribute names. The JSR 168 specifications also require that we declare the user profile attributes that are accessed by the application in the portlet.xml deployment descriptor.

Mainsoft provides a Visual Studio based Portlet Designer that will save you the time and energy you would otherwise need in learning the JSR 168 specification details. To fetch the user profile vales, simply open the portlet.xml file (under the WEB-INF directory in the Solution Explorer), and Visual Studio will open it in Mainsoft Portlet Designer. Click the Edit User Attributes... button (see Figure 8). This dialog allows you to declare JSR 168 user profile attributes that are used by your application (see figure 9).

We will use the user profile values in the next section.

Adding people awareness to your application

Let’s see how to use WebSphere Portal’s people awareness, a WebSphere Portal feature that integrates with Lotus SameTime collaboration products and is in high demand. One feature, the presence awareness system, alerts you when your colleagues are online, so you can collaborate more easily and get your work done more efficiently. Mainsoft, Portal Edition, makes it easy to use people awareness in ASP.NET portlets. Mainsoft provides an ASP.NET server control named wpPerson that can be dragged and dropped to the ASPX designer from one of Mainsoft’s toolboxes, called IBM WP Web Forms.

Drag a Label control to ViewForm.aspx and label it Welcome.

Next to it, add people awareness to your application by dragging-and-dropping the wpPerson control into your application. The following code in the page_load event uses the user profile you already fetched to feed the wpPerson control:

//Display the user profile information in the wpPerson
    control
//If user profile information is not available, display
    Portal login id 
//through ASP.NET Principal that is initialized automatically
    by the
//Mainsoft Portal Authentication Module
WpPerson1.DisplayName = ((GivenName != null) || (FamilyName != null)) ?
            GivenName + " " + FamilyName : Context.User.Identity.Name;


//Send an email menu will appear only if email address
    is available
if (Email != null) //Disable email menu if null
{
   WpPerson1.ValueType = Mainsoft.Web.Controls.WebSphere.
        wpPersonValueType.EMAIL;
   WpPerson1.Value = Email;
}
else
   WpPerson1.Value = WpPerson1.DisplayName;
						

Note that this user is the identity of a user in Workplace client technology. If your system is integrated with Workplace, you will get a number of additional features, which users can use to interact with each other.

Integrating with portal preferences and using Edit mode

Figure 10. Supporting the portlet Edit mode to personalize the portlet.

Figure 11. Editing your portlet.

Figure 12. Creating the Edit Form.

Let’s now add another page to allow the application users to customize their ASPNETFolio application by selecting a stock exchange. We will leverage the JSR 168 Edit mode for this purpose and the integrated Mainsoft Portlet Designer. The JSR 168 specifications define several portlet modes: the default (and mandatory) mode that you have used up to now is called the View mode. In addition, there are also Edit, Config, Help, and edit_defaults that are optional modes.

Open the Portlet Designer and select the Portlet Modes property to open the Select Portlet Modes dialog box (see figure 10). Enable the Edit mode and create its start page, just type EditForm.aspx, and press OK. This will add a new ASP.NET page into your project named EditForm.aspx. It also tells the JSR 168 portlet container that your portlet supports the Edit mode, and the portal will display the Personalize menu item in the portlet control toolbox.

Now, whenever you select the Personalize menu item in your portlet control toolbox, the EditForm.aspx will be launched (see Figure 11).

Next, add code to the edit page that will get called when your users select Personalize for the portlet.

Add two labels - a drop-down list and a button - to this Web Form as in Figure 12.

In the Page_Load event of the EditForm.aspx, add the code:

DropDownList1.Items.Add("NASDAQ");
DropDownList1.Items.Add("AMEX");
DropDownList1.Items.Add("NYSE");
// Initialize the DropDownList with the current
// portlet
// preference value accessed through ASP.NET
// Profile
if (!IsPostBack)
   DropDownList1.SelectedValue =       
          (String)Context.Profile["Exchange"];
						

The JSR 168 Portlet Preferences is meant for storing portlet customization data. Mainsoft has mapped the ASP.NET profile custom properties to the JSR 168 portlet preferences as part of WebSphere Portal’s specialized ASP.NET Profile provider.

So we just have to define a new ASP.NET profile property in our web.config inside the property section:

<profile enabled="true" defaultProvider="WPProfileProvider"
inherits="Mainsoft.Web.Profile.WPUserProfile">
      <properties>
        <add name="Exchange" defaultValue="NASDAQ"></add>
      </properties>
</profile>
						

In the click event handler for the Submit button, we need to update the profile property, stored as a portlet preference, with the drop-down list selected value:

// Update the portlet preference through ASP.NET
    profile
Context.Profile["Exchange"] = DropDownList1.SelectedValue;
						

Now, your users will expect to return to View mode and to a NORMAL window state (the Edit mode will run by default in MAXIMIZED) once they click on Submit. To programmatically switch portlet modes and window states, you need to invoke the JSR 168 APIs. Mainsoft provides you with a portlet-api reference that exposes all the JSR 168 classes and all the WebSphere Portal public APIs and SPIs (Service Portlet Interfaces). Additionally, to ease the access to the inner JSR 168 objects from the ASP.NET page, Mainsoft also provides you with a specialized portal page that defines properties for all the JSR 168 objects you need to access:

// Return to View mode and normal state
// Access to ActionResponse by casting JSR168 PortletResponse
// PortletResponse is accessible through a
// Mainsoft.VMW.Portal.Page property
// Button click events are always invoked 
// in the Action phase, no need to check cast
javax.portlet.ActionResponse ar =     
    (javax.portlet.ActionResponse)this.PortletResponse;
ar.setPortletMode(javax.portlet.PortletMode.VIEW);
ar.setWindowState(javax.portlet.WindowState.NORMAL);
						

Notice that your ASPX pages inherit from this Mainsoft.Web.Portal.Page.

public partial class EditForm : Mainsoft.Web.Portal.Page
						

The stock exchange property stored in the portlet preferences is also used in the View mode Form to display the stock exchange that is currently selected.

Add a label to your ViewForm.aspx file that will fetch the ASP.NET property:

Label1.Text = "selected stock exchange is " +
Context.Profile["Exchange"];
						

You can see the entire interaction with the ASPNetFolio portlet in Figures 13a, 13b, and 13c. You can find the code for the ASPNetFolio portlet under the Mainsoft samples folder: <Mainsoft_install_dir>\Samples\{CS|VB}\WebSpherePortal\ASPNETFolio.

Figure 13a. I am signed into my portal and seeing the portlet in view mode.

Figure 13b. I enter Edit mode and change the stock exchange.

Figure 13c. I am selecting the people awareness control.

Summary

This article took you step-by-step through the process of using the Visual Studio IDE, C#, and ASP.NET server controls to develop an ASP.NET portlet that runs natively on IBM WebSphere Portal as a JSR 168 compliant portlet.

We also ventured into new territory, enabling tight integration and interoperability with the JSR 168 and the WebSphere Portal stack. Once you’ve mastered these development techniques, you can access WebSphere Portal’s many end-user features from your ASP.NET portlets, including branding, people awareness, portlet modes, user profiles, and portlet preferences.

And that’s it! You have the tools you need to build a fully integrated WebSphere Portal environment with all the rich end-user functionalities that make WebSphere Portal the industry’s leading portal environment.

Enjoy!


Listing 1:

<portfolios>
	<portfolio exchange='NASDAQ'>
		<item>
			<ticker>SUNW</ticker>
			<pp>5.15</pp>
			<qty>100</qty>
			<cp>0</cp>
			<cv>0</cv>
			<del>0</del>
		</item>
		<item>
			<ticker>EBAY</ticker>
			<pp>32.20</pp>
			<qty>50</qty>
			<cp>0</cp>
			<cv>0</cv>
			<del>0</del>
		</item>
		<item>
			<ticker>INTC</ticker>
			<pp>18.20</pp>
			<qty>1000</qty>
			<cp>0</cp>
			<cv>0</cv>
			<del>0</del>
		</item>
	</portfolio>
	<portfolio exchange='AMEX'>
		<item>
			<ticker>XLE</ticker>
			<pp>58.51</pp>
			<qty>100</qty>
			<cp>0</cp>
			<cv>0</cv>
			<del>0</del>
		</item>
		<item>
			<ticker>IWM</ticker>
			<pp>77.45</pp>
			<qty>500</qty>
			<cp>0</cp>
			<cv>0</cv>
			<del>0</del>
		</item>
		<item>
			<ticker>IIP</ticker>
			<pp>1.39</pp>
			<qty>1000</qty>
			<cp>0</cp>
			<cv>0</cv>
			<del>0</del>
		</item>
	</portfolio>
	<portfolio exchange='NYSE'>
		<item>
			<ticker>DIS</ticker>
			<pp>29.19</pp>
			<qty>1000</qty>
			<cp>0</cp>
			<cv>0</cv>
			<del>0</del>
		</item>
		<item>
			<ticker>LU</ticker>
			<pp>2.77</pp>
			<qty>50</qty>
			<cp>0</cp>
			<cv>0</cv>
			<del>0</del>
		</item>
		<item>
			<ticker>TWX</ticker>
			<pp>17.04</pp>
			<qty>100</qty>
			<cp>0</cp>
			<cv>0</cv>
			<del>0</del>
		</item>
	</portfolio>
</portfolios>
						

Listing 2:

using System;
using System.Data;
using System.Configuration;
using System.Xml;
using System.IO;

using ASPNETFolio.net.webservicex.www;

namespace ASPNETFolio
{
    //Data Access Layer: Portfolio class obtains stock
        quotes
    //from http://www.webserviceX.NET online web service
    public class Portfolio
    {
        //Portfolios are defined in Xml file
        private String portfolioFile = "portfolios.xml";        
        private XmlDocument portfolioXml;
        
        public Portfolio()
        { 
            portfolioXml = new XmlDocument();
            portfolioXml.Load(portfolioFile);
        }
    

        //Unique public method to be used by DataSource as
            Select and
        //Update Method
        public DataSet GetPortfolioData(String exchange)
        {
            //Load xml into a DataSet
            XmlNode portfolioNode = portfolioXml.SelectSingleNode(
                "//portfolios/portfolio[@exchange='" + exchange + "']");
            this.GetCurrentValues(portfolioNode);
            DataSet ds = new DataSet();
            ds.ReadXml(XmlReader.Create(new StringReader(
                ("<data>" + portfolioNode.InnerXml + "</data>"))));
            return ds;
        }

        //Get Stock list current values.
        private void GetCurrentValues(XmlNode portfolioNode)
        {
            foreach (XmlNode item in portfolioNode.SelectNodes("//item"))
            {
                string ticker = item.SelectSingleNode("ticker").InnerText;
                Decimal purchase = Convert.ToDecimal(
                    item.SelectSingleNode("pp").InnerText);
                int qty = int.Parse(item.SelectSingleNode("qty").InnerText);
                Decimal currentPrice = GetQuote(ticker);
                item.SelectSingleNode("cp").InnerText =
                    currentPrice.ToString();
                item.SelectSingleNode("cv").InnerText =
                    (currentPrice * qty).ToString();
                item.SelectSingleNode("del").InnerText =
                    ((currentPrice - purchase) * qty).ToString();
            }
        }

        //Get the stock value from the http://www.webserviceX.NET
        //online web service
        private Decimal GetQuote(string ticker)
        {
            try
            {
                StockQuote sq = new StockQuote();
                string stockXml = sq.GetQuote(ticker);
                XmlDocument stock = new XmlDocument();
                stock.LoadXml(stockXml);
                return Decimal.Parse(
                    stock.SelectSingleNode("//Last").InnerText);
            }
            catch
            {
                //failed to get the quote from the WS
                return 0;
            }
        }
    }
}
                    

Display a printable version of this page     Email this page     Add to favorites     This page has been viewed 34898 times.


Home  Site map  Privacy statement  Legal notice  Contact us
Mainsoft Product Validations: Optimized for Microsoft Visual Studio, Java Powered for the Enterprise, and Ready for IBM WebSphere.
Read more about: .NET Java and .NET for Linux

Copyright © Mainsoft Corporation 2005-2009. All rights reserved