AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=285&pId=-1
Consume User Controls in non-ASP.NET Sites
page
by Steve Sharrock
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 12526/ 15

Consume User Controls in non-ASP.NET Sites

ASP.NET User Controls are both easy to create and easy to use; however, they're designed to be used from within a single web application. To use the same control in a different application you must copy your control's .ASCX (and associated files) to a virtual directory within that application. This article describes a simple trick that allows you to publish a page for another site that contains your site's User Control, or any other dynamic content. In fact, the other site doesn't even need to be an ASP.NET web site.

I discovered this little trick recently after I implemented the Amazon.com Web Services interface to my consulting home site. The Web Service from Amazon allows me to request details, including an image url, for a list of books identified by their Amazon ID (ASIN). I display the list of books in a DataGrid bound to a DataSet that I create from the information returned by the Amazon Web Service. I wrapped the DataGrid presentation and Web Service reference within a simple User Control.

A friend of mine that runs a cooking site was tired of building all of the Amazon "associates" links manually and wanted to use the same technique as I had for my book list. The cooking site is simple HTML hosted with an inexpensive ISP. My friend just wanted to link to my site and provide their own list of books.

It's no trick to simply provide a link that returns a complete page for a list of books identified with their ASINs in the link's query string. But of course the generated page doesn't have the same look-and-feel as the calling web application--the cooking site in this case. The simple solution I chose to present the same look-and-feel as the calling site was to require not only the list of books in the link's query string, but also the URL of a "template" page into which I could insert my DataGrid's rendered output.

The page on my site to which the cooking site links contains only three elements: a "top" literal control, a placeholder for my User Control, and a "bottom" literal control.

<%@ Page language="c#" Codebehind="BookList.aspx.cs"
    AutoEventWireup="false" Inherits="Books.BookList" %>
<asp:Literal id="topLiteral" runat="server"></asp:Literal>
<asp:PlaceHolder id="ctrlPlaceHolder" runat="server"></asp:PlaceHolder>
<asp:Literal id="bottomLiteral" runat="server"></asp:Literal>

The caller (cooking site) links to my book site requesting the book list with a link similar to:

<a href="http://www.booksite.com/BookList.aspx?
  TEMPL=http://www.cookingsite.com/BookTemplate.htm
  &ASIN=0735613702,0735614229>My Books
</a>

When the incoming request hits my book site, I first "screen-scrape" the template page identified in the query string from the callers site using a WebClient object. Using a simple regular expression, I match a predefined "tag" in the template page's text, "<BOOKLIST />" in this case. I then set my page's "topLiteral" text with all of the template page's text that appears before the tag, and I set my page's "bottomLiteral" with all of text that appears after the <BOOKLIST /> tag. The only thing that remains is to set the Placeholder that appears between the top and bottom literals to an instance of my BookList User Control.

private void Page_Load(object sender, System.EventArgs e)
{
  string text;

  try
  { // screen-scape the template page text
    byte[] bytes = new WebClient().DownloadData( Request.QueryString["TEMPL"] );
    text = new UTF8Encoding().GetString( bytes );
  }
  catch
  {
    text = "";
  }
  // find the <BOOKLIST />tag
  Match m = Regex.Match( text, "<BOOKLIST />",
             RegexOptions.IgnoreCase );
  if ( ! m.Success )
  {
    DoError("Missing <BOOKLIST />");
    return;
  }
  // set top and bottom literals from template page
  topLiteral.Text = text.Substring(0, m.Index );
  bottomLiteral.Text = text.Substring( m.Index + m.Length );
  
  // create User Control and set ASIN (book) list
  BookListCtrl ctrl = (BookListCtrl)this.LoadControl("BookListCtrl.ascx");
  ctrl.Asin = Request.QueryString["ASIN"];
  ctrlPlaceHolder.Controls.Add(ctrl);
}

I removed most of the error checking and used a rather simplistic regular expression to make the example clearer. Note that the User Control (BookListCtrl) provides a public property called Asin that I set with the comma delimited list of Amazon IDs passed in the query string.

Run Example

You can see an example using each of the following links to provide the same list of books for my personal consulting site and my AspAlliance author's site.

My Consulting Books
My AspAlliance Books

These two examples use a modification of the technique outlined above. Each sites template page specifies a common XML file that contains the ASINs and optional descriptions.

Summary

This simple example can be extended easily to use a broader range of predefined "tags" that request more information. In my final implementation of the BookList, I allowed the caller to specify the list of book ASINs from within the template page between <BOOKLIST></BOOKLIST> tag pairs. I also allow the caller to include comment text that I include with each book description. And of course, you could parse the template looking for more than one predefined tag.

Send your comments and let me know what you think of this article: steve@sharkcode.com

Steve Sharrock -   www.AspAlliance.com/shark / www.SharkCode.com



©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-19 11:32:31 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search