# Installation and Development Guide

# Configuration and Development -
.NET Web Control Consumer (WCC)

The .NET Application Accelerator's Web Control Consumer (WCC) package includes support for standard .NET Web Controls within AquaLogic Interaction. This chapter assumes that the reader is familiar with standard portlet development practices as detailed in the AquaLogic Interaction Development Documentation ( http://download.oracle.com/docs/cd/E13174_01/alui/devdoc/docs60/index.html).

- Introduction - Why WCC?
- Additional Configuration Steps
- Development Best Practices
- Migrating Existing WCC Applications

## Introduction - Why WCC?

Two problems arise with using .NET Web Controls out of the box for portlet development:

- Client-side scripting problems arise due to naming collisions; .NET assumes it occupies the whole page, and all specific functions are always named the same. These problems occur primarily with validator controls. Validator controls define a page scope variable (Page_Validators), a page scope function (ValidatorOnSubmit()), and also write some inline JavaScript code. All of these problems are overcome by the .NET Web Control Consumer.
- Postback problems are a little more complex; they cause naming collisions in addition to posting back to the incorrect page. The preferred behavior for Web Control is generally an in-place refresh. For example, when a user selects the next month in the Calendar control, it posts back to the originating aspx page. Even though the post goes through the gateway, it is not sent to the portal page that hosted it, and the user loses the portal experience. .NET Web Control Consumer modifies postback functions to solve this problem.

The .NET Web Control Consumer package overcomes these problems and provides a simplified experience for portlet developers. The core of the package is a .NET HttpModule that modifies the outgoing HTML before it reaches the portal server. The module solves the problems described above by: a) individuating all .NET provided function names to avoid collisions, and b) modifying all postback functions to use JavaScript instead of posting directly to the server.

## Additional Configuration Steps

This section explains additional configuration steps for the .NET Web Control Consumer.

Alternative Image Service Access: If the URL used to access your Image Service internally is different from the URL used for external access, and your portlet server is hosted internally, follow these steps to define the Image Service address.

Logging: AquaLogic Interaction Logging Spy logging functionality is enabled by default. These instructions explain how to disable logging by either ALI Logging Spy or log4net.

Future Framework Support: Use these instructions to add support for any .NET Framework version that uses JavaScript WebUIValidation.

Portlet Configuration: To configure an existing .NET application to be used in AquaLogic Interaction, use these steps to make a new entry in the Web application's web.config file.

### Alternative Image Service Access

Some network configurations require that the portal Image Service (previously called Image Server) is accessed through a different URL internally and externally. This can be a problem for portlet servers that are hosted internally because AquaLogic Interaction always sends the external Image Service URL (the portlet must contact the Image Service to retrieve auxiliary JavaScript files).

If this is the case, set up a mapping to allow the portlet server to determine the internal Image Service address. This can be achieved in two ways.

The simplest way is to map the external image server to the internal URL by doing the following:

1. Open imageserver.mapping.xml in a text editor. The file is located in the .NET Web Controls installation folder, under \settings\config.
2. Add a new entry for the internal Image Service, as shown below:

    <mapping find="http://www.external-servername.com/ptimages/" replace="http://internal-servername:8080/ptimages/"/>

You must include the whole URL. Sections of the URL will NOT be replaced. To replace sections, you must use a regular expression mapper, as shown below:

    <mapping regex="true" find="www.external-(\w+).com" replace="internal-$1:8080" />

Both mappings do the same thing in this case. For details on syntax, see .NET regular expressions.

3. Save the imageserver.mapping.xml file.
4. Restart IIS or re-save the config.xml file located in the same directory (this instructs the Web Controls to reload all configuration settings).

The second option is to set an alternative Image Service URL to override the external URL, using an Administrative preference. The default setting name is PTWC.Mapping.Override (this name can be changed in the HttpPipe.xml file). You must create an administrative preferences page to set the preference.

Note: | This granularity of configuration is not generally necessary except for specific remote portlets that access the Image Service through a specific unique URL.

### Logging

The .NET Web Control Consumer supports logging, which is primarily used for troubleshooting, either in the case of an internal error or configuration problem, or to view operations that the .NET Web Control Consumer is performing. By default, AquaLogic Interaction Logging Spy and one file logger logging at INFO level are configured.

The file logger is a log4net rolling log file appender, which logs to the settings/logs directory in the installation directory. Any problems encountered by the .NET Web Control Consumer are logged here. Under normal circumstances, you will not need to view this log unless problems occur.

When configuring additional options (such as internal Image Service mapping), you can confirm your changes by running AquaLogic Interaction Logging Spy (ptwc/3.0/bin/assemblies/ptspy.exe) and configuring the "Web Services - Portlet API" component to run at DEBUG level and making sure that the options are correctly applied.

To disable existing logging, remove its `<logconfig>` section from the config.xml file.

### Future Framework Support

The .NET Web Control Consumer is shipped with support for a few explicit versions of the .NET Framework. You can add support for any .NET Framework version that uses JavaScript WebUIValidation (version 125) using the JSGenerator application. To generate a new version of JavaScript files, follow the steps below:

1. Start the JSGenerator application by running JSGenerator.exe located in the \bin directory of the .NET Web Control Consumer installation directory.
2. Select the new Framework version from the list, or enter the version in the format X.X.X.X. (The list includes all versions available on the local machine.)
3. Click Generate.
4. Once generation is complete, the application provides instructions on where to copy the new files to the Image Service.
5. Copy the files.

Once you have copied the files, the new Framework will be supported.

Note: | Only WebUIValidation version 125 is currently supported.

### Portlet Configuration

To configure an existing .NET Web application to be used in AquaLogic Interaction, you must make a new entry in the Web application's web.config file. In the /configuration/system.web node, add a new node that specifies the HttpModule class and containing assembly, as shown:

    <httpModules>

    <add type="Com.Plumtree.Remote.Loader.TransformerProxy, Aqualogic.WCLoader, Version=3.0.0.0, Culture=neutral, PublicKeyToken=d0e882dd51ca12c5" name="PTWCFilterHttpModule" />

    </httpModules>

Note: | The `<add>` section must be entered on one line. If you cut and paste the code from this document, make sure to remove the word wrap breaks or your code will not work.

Once you add this entry, all gatewayed requests to the Web application are transformed for use with AquaLogic Interaction. You can still access your Web application directly; the module is bypassed for any request that does not originate from a portal server. For example templates, see the following folders in the installation directory: \deploy\web.config (sample web.config file) and \deploy\web.config.node (node only).

Note: | Any .NET portlet page that performs postbacks (including auto-postback) must be gatewayed (which is included in the list of gateway prefixes in the Portlet Editor). For details on configuring the gateway, see the AquaLogic Interaction Development Documentation or the portal online help.

Your IIS Web Application Server must have direct Web access to the Plumtree Image Service.

## Development Best Practices

This section includes additional best practices related to the .NET Web Control Consumer.

- Postbacks
- Unique Naming
- Submit Buttons
- File Upload
- Custom JavaScript
- Filter Disabling
- Development Checklist

For more tips and tricks, see the .NET WCC FAQ: http://download.oracle.com/docs/cd/E13174_01/alui/devdoc/docs60/ index.html#References/FAQ_PlumtreeNETWebControls.html.

### Postbacks

The .NET Web Control Consumer module enables the use of .NET Web Controls and their associated AutoPostBack function. All automatic postbacks are caught and used to repaint the individual portlet. The module makes a number of modifications to the HTML; below is an overview of the modifications you should be aware of:

- Because all POSTs are handled by JavaScript, they do not become part of the browser history. This means that JavaScript functions will not work; the Back and Forward buttons of the browser will skip any clicks made on Web Controls that are handled in this way.
- All requests from a portal server are transformed; navigating to the portlet directly does not yield the same HTML that is returned to the portal server. This allows the ASPX page to be accessed directly if required (the modified page would not function outside the portal environment). To examine the HTML going to the portal server, use a trace tool between the portal and the portlet server to intercept the HTML.
- All client-side validation script is transformed, but since ASP.NET only generates client-side script for specific versions of Internet Explorer (IE), nothing is altered for browsers other than IE.
- All .NET portlets are wrapped in an HTML span. Do not assume that the portlet is at any specific point in the HTML structure of the page; portlet parent elements are usually HTML table cells, but not in this case.
- The `_doPostBack` method is removed (a similar function is included in an additional JavaScript file). Beware of hooking into this .NET-provided function directly; both the function name and argument list are modified. Any direct calls to this function should also be modified automatically, however any non-standard calling conventions could potentially not be recognized by the module. To programmatically perform a postback from JavaScript, make the call `_doPostBack('','');`.
- Always use FlowLayout because GridLayout uses absolute positioning.
- The names for HTML spans (for validators) and forms (required for all pages that perform a postback) are appended with a unique ID (portlet ID), to avoid naming collisions on a portal page. Do not refer to these names directly in JavaScript. (If it is absolutely required, you can assume that they will be named <original-name>_<portlet-id>.)

### Unique Naming

Generally all HTML elements should be named uniquely, which normally involves appending the portlet ID to the element name. This can be problematic with ASP.NET, because the Web Control names and IDs cannot be generated at runtime in the normal ASPX syntax. For example the following code will not work:

    <asp:Button id="Execute_<%= portlet_id %>" runat="server" Text="Test"></asp:Button>

The best way to append the portlet ID to the name is programmatically. To do this, declare the control in the ASPX page with a standard name, and then modify the ID property from the code behind page. You can access the actual controls using the `System.Web.UI.Page Controls` property or the `System.Web.UI.Page FindControl(string ControlName)` method.

For example, to append the portlet ID to a control named "MyButton," the following code could be employed:

    protected override void OnPreRender(EventArgs e)
    {
    base.OnPreRender (e);
    FindControl("MyControl").ID += portletID;
    }

Note: | It is simplest to append the ID using the page's PreRender event so that the standard ID is used until the last possible point.

### Submit Buttons

Submit buttons will normally be modified to remain in the portal context. This was not the case in the 2.1.x release; in that release, they required an additional ptrender attribute. This now defaults to true, although it can be disabled by adding a `ptrender=false` attribute to the button.

Note: | As in the 2.0.x release, it is still possible to place a ptrender tag on the form itself. This means that anything attempting to submit the form will cause it to be posted back in-page. However, we recommend using the tag on the buttons, unless it is specifically required (for example, a third-party control is attempting to submit the form directly).

The standard method of posting to the target page and redirecting back to the portal page using the IDK is also possible, however this is generally slower (performs a post and a redirect), less aesthetically pleasing (refreshes the whole page), and will lose the state of the page if handled by the client (`__VIEWSTATE` will be lost).

### File Upload

In-page uploading is not supported. Any upload forms (multipart/form-data) will not be posting in-page and will post as normal through the gateway. Make sure to redirect back to the hosting page if uploading is required, or to perform the upload in a popup or non-aggregated page.

### Custom JavaScript

Because each page refresh dynamically writes the HTML to re-render the portlet, custom JavaScript can pose a problem. Because any JavaScript is now executing as the portlet is rendering, there are some functions that will not work correctly. Any document.write(..) calls will not work.

To call a script each time the page is refreshed (or every time the portlet is re-rendered), use the rerenderPortletID PCC event. This event is available only to .NET portlets and is named using the current portlet ID.

For example, to create a JavaScript alert each time the portlet is rendered, use the code below.

Note: | JavaScript is executed for each postback; make sure that the script to register for the event is only included in the first page; otherwise the function will be registered multiple times.

    <pt:namespace pt:token="$$PORTLET_ID$$" xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'/>

    function alertMe_$$PORTLET_ID$$, () {

          alert("Portlet Rendering!");

    }

    alertMe_$$PORTLET_ID$$;//call the first time the portlet is loaded

Then register for the event in the code behind:

    		private void Page_Load(object sender, System.EventArgs e)

    		{

    			if(!IsPostBack)

    				RegisterClientScriptBlock("rerender", "<script language=\"javascript\">document.PCC.RegisterForWindowEvent('rerender.$$PORTLET_ID$$', alertMe_$$PORTLET_ID$$)</script>");

In the example above, $$PORTLET_ID$$ is replaced by the portlet ID using the pt:token adaptive tag. You can also use the IDK to extract the portlet ID from the request. See the AquaLogic Interaction Developer Documentation for more information on adaptive tags.

### Filter Disabling

Under some circumstances, it may be desirable to disable the HTML filtering. Pages opening in popup windows or operating in gatewayed mode will probably not want any HTML modification. Therefore filtering can be disabled per-request by making the following call:

    Context.Items["PTWC:EnableFilter"] = false;

This will disable filtering for the current request only.

### Development Checklist

Follow the basic guidelines below in any portlet that uses the Plumtree .NET Web Control Consumer:

- Name all elements uniquely.
- Do not assume your code is in a particular location in the HTML DOM.
- Do not rely on back/forward buttons or JavaScript commands.
- Do not access validator spans directly.
- Use FlowLayout instead of GridLayout.
- Always include the target page in the gateway space.

## Migrating Existing WCC Applications

This page provides basic instructions for migrating applications built with the 2.1.x version of the WCC. Migrating from versions 2.2.x and above requires no changes to the existing code.

### 2.1.x to 3.0

Even though 3.0 and 2.1.x are very similar, there are some differences that might require some changes to existing code.

#### JavaScript Execution

In 2.1.x and earlier, JavaScript was executed only upon the first rendering of the page. Some applications may be using this assumption that inline code will be run only once, therefore, as this is no longer true, it must be modified to run only once. This can be done easily on the server, by including the code only if IsPostBack == false. This can also be done on the client a few ways, such as:

    <script>

    	if(!already_run)

    	{

    		//run my code here...

    		var already_run = true;

    	}

    </script>

Many existing applications register for PCC events upon the initial render; this code must be changed to prevent multiple PCC registrations.

#### ptrender for Buttons

In 2.1.x, buttons would NOT submit a form in-page by default; adding a ptrender=true attribute to the button would cause this behavior. The default behavior now is to submit the form in-page, which can be disabled by added a ptrender=false attribute to the button. Therefore if there are buttons relying on the default behavior of not performing an in-page refresh, these must be changed to include a ptrender=false attribute (note that including a ptrender=true attribute now has no effect).