Digital Colony!

Masking Email Addresses in PHP

Steve Waag from Lacanche Ranges was able to translate the ASP in Masking Your Email Address to PHP.
<?php
function maskEmail($email) {
  $maskedEmail = '';
  for ($j = 0; $j < strlen($email); $j++) {
    $maskedEmail .= '&#' . ord(substr($email, $j, 1)) . ';' ;
  }
  $emailHtml = '<a href="m&#' . ord('a') . ';&#' . ord('i') . ';&#' . ord('l')
    . ';&#' . ord('t') . ';o:' . $maskedEmail . '">' . $maskedEmail . '</a>';
  return $emailHtml;
}
?>

<p>For more information email me at
  <?php echo maskEmail('someEmail@someDomain.net') ?>.</p>

Labels: , ,

 

My First ADO.NET Table

This article was written in 2002 and is based upon ASP.NET 1.0.

The most common data centric task an ASP developer can do is create an HTML table from an SQL query. Below is an example of how to do this with ASP.NET. I'll be connecting to a SQL Server database, but with some slight modifications this code will work for an OLE-DB provider or OLE-ODBC driver. The 3 objects used in this example are SQLConnection, SQLCommand and the SQLDataReader.

Namespace

In order to access data objects a few namespaces are required. The first is System.Data. It contains the basic ADO.NET objects. The second namespace will depend upon your data source. If it is SQL Server then you will use the System.Data.SQLClient namespace. If it isn't then use System.Data.OleDb.
<%@Page Language="VB" %> 
<%@Import Namespace="System.Data" %> 
<%@Import Namespace="System.Data.SqlClient" %>

Connection

For SQL Server the object used to connect to the data source is SQLConnection. Ole-DB requires the OleDbConnection. Like the ADOB.Connection object in classic ADO, this also requires a connection string.
'-- SQL Server Example 
Dim strConnect As String 
strConnect = "server=localhost;database=elvis;uid=king;pwd=tcb;" 
Dim objConnection As New SQLConnection(strConnect) 
objConnection.Open 

Command

Now that I've connected to the data source, we will want to execute an SQL query against it. In this example I want a list of all Elvis movies. The SQLCommand object allows us to execute our SQL statement against the data source. Ole-DB users will use the OleDBCommand object.
Dim strSQL As String 
strSQL = "SELECT filmName, yearReleased FROM TCBFilms" 
Dim objCommand as New SQLCommand(strSQL,objConnection)

DataReader

The DataReader object is way to access the returned data quickly. It is similar to ADO's Recordset object. In the this example, I'll connect the DataReader to an asp:datagrid servers-side control. This will create an HTML table with column headers. No more iterating through the Recordset row-by-row writing HTML to the screen for each row. Ole-DB should use the OleDBDataReader object.
Dim objDataReader as SQLDataReader 
objDataReader = objCommand.ExecuteReader() 
myDataGrid.DataSource = objDataReader 
myDataGrid.DataBind() 
objConnection.Close()
<asp:datagrid id="myDataGrid" runat="server" />

Last Words

This is the just a basic example of using ADO.NET objects to create a database driven HTML table with ASP.NET. ADO.NET has many more powerful features including handling disconnected data and working with XML.

Labels: , , ,

 

ASP Photo Gallery v3

The original ASP Photo Gallery v3 code was written in 2002.

ASP Photo Gallery v3 added thumbnails to ASP Photo Gallery v2. I've removed the v3 code and article from this web site. It was a complete hack that required Classic ASP components that didn't create quality thumbnails. It was not built to handle the much larger image sizes cameras produce today. Therefore I believe it is rarely practical to store and manipulate images on a shared web host, especially using Classic ASP image components. Use a dedicated company like SmugMug or Flickr and then access their APIs to build custom galleries. For a simple gallery using the SmugMug RSS feed, read my tutorial Displaying a SmugMug Gallery with ASP.NET

Labels: ,

 

Building a Database Driven Table in Classic ASP Part 2

The article was written in 2001.

In Part 1, we split the rendering of database-driven HTML tables into 3 parts: Establishing a Database Connection, Getting a RecordSet, and Drawing the TABLE. In this part, we will clean up the column headers, add sorting, and paging.

Renaming Columns

Sometimes you'll want to have the table columns named differently than the columns in the database. Fixing this is as a simple as modifying the SQL query. By aliasing the fields in the query, we can rename the columns.
' original query that renders ugly column headers 
sSQL = "SELECT E.fname, E.lname, D.name FROM Employee E, Department D WHERE E.deptId = D.deptId " 

' aliased query that generates nice column headers 
sSQL = "SELECT E.fname AS FirstName, E.lname AS LastName, D.name AS Department " &_ 
"FROM Employee E, Department D WHERE E.deptId = D.deptId "

Sorting

We can add generic sorting functionality to our table with just a few lines of reusable code. The first version of the sort doesn't require javascript and will work on every browser.
<% 
sSQL = "SELECT CompanyName, ContactName, ContactTitle, City FROM Customers " 
' the sort sequence will be passed in from the querystring 
sort = Request.QueryString("s") 
If len(sort) > 0 AND IsNumeric(sort) Then 
  sSQL = sSQL & " ORDER BY " & s 
End If
Set rs = Server.CreateObject("ADODB.Recordset") 
Set rs = ac.Execute(sSQL) 
%>
'  Update the column code in the drawTable subroutine 
Response.Write "<tr>" 
intColumn = 1 
strPath = Request.ServerVariables("PATH_INFO") 
For Each field In rs.Fields    
   Response.Write "<th><a href=""" & strPath & "?s=" & intColumn & """>" & field.name & "</a></th>"    
   intColumn = intColumn + 1 
Next 
Response.Write "</tr>" & chr(10)

Paging

With large recordsets, we may only want to return a limited number of records. By limiting the number of records returned, the page renders faster. For a detailed tutorial on ADO paging read Recordset Paging with ADO 2.0 by Michael Qualls. We want to add generic code that will work with any query. Inside the connect.asp file there will be a new subroutine called drawPaging.

Files

View the updated source of table.asp.txt and connect.asp.txt.

Last Words

In Part 1 and her in Part 2, we created some generic code libraries to connect to a database, return a recordset, and then draw an HTML table that supports sorting and paging. This code will allow us to quickly generate reports in ASP.

Labels: , , ,

 

ASP Photo Gallery v2

This article was written in 2001. It has a good example of how Classic ASP can use an XML file as a data source. However, I wouldn't use it today to create a photo gallery. There are much better options out there. With that said, this code is no longer supported.

In the article Creating an ASP Photo Gallery, I showed you how to create a very basic photo gallery using just a few lines of ASP code. It was quick and dirty, however, it had limitations.

The first limitation was that all the photos had to be the same size. You could remove the width and height tags from the image, but that is clumsy coding and browsers always render non-sized images funky. The second problem was that we had to rename the images to a number and then maintain a sequence. If you have 5 images that isn't a problem, if you have 100 it becomes tedious. And the last thing missing was the ability to quickly add titles, descriptions, and alt tags for each image.

Choosing a Weapon

OK, we need to store and maintain data about the picture. We have 3 options. Option 1 - We build data arrays on the actual ASP page and populate it there. This is not a clean design. Ideally we want to keep the data and code separated in order to support code reuse. Option 2 - Create a database. Building a database in Access or MySQL is easy enough, but it's overkill for a single photo gallery. Do we really want to setup connection strings and deal with versioning and licensing issues for such a small dataset? No. Option 3 - XML. With XML we can keep the data apart from the code and we don't need a database.

The XML Image File

The XML image file will capture a sequence number, the file name, image width, image height, short caption, long description, and an image ALT tag.
<?xml version="1.0"?> 
<images> 
  <image num="1" file="me.jpg" width="400" height="302" short="Me" long="Me at  Graceland." alt="photo"/> 
</images>

What Can We Automate?

I don't know about you, but I'm not going to fire up an editor and hack out the XML image file. The code should generate most of the body of the file with the exception of the short, long, and alt descriptions. We can use the FileSystemObject to detect images. From this point, we can use the Microsoft.XMLDOM object to build the XML for the photo gallery. Once that is created, wouldn't it be nice to go through the gallery and assign those values in a form? As for the image width and height, we can use client-side javscript to calculate those values the first time that the gallery is viewed.

Security

Since we don't want other users modifying our image captions, we will assign a password to gallery. The password is passed in the querystring under the parameter k and will open the Admin FORM. Example: gallery.asp?k=password&pic=1. This will also give you the power to make text changes from any browser.

Other Admin Features

Besides saving image attributes, the Admin form will allow you the ability to remove an image. The image is removed from the XML file, not the server. And should you upload additional images or accidently remove an image you need, there is a Detect Images buton which will append an image file found in the image folder that doesn't appear on the XML image file.

Setting Up The Photo Gallery Page

My first goal was to make this code as easy as possible for a non-techie to use. The best way to pull that off is to hide all the gritty file detection and XML manipulation in a separate file. All coding logic is kept in an include file called galleryCode.asp. The 2nd file is the ASP file used to house the image gallery. At the top of this file we need to define the following:

key - This is password you'll use to access the gallery as an administrator. galleryURL - The URL to the photo gallery from the root (the virtual path). galleryASP - The name of the ASP page of the actual photo gallery. galleryImageURL - The URL (virtual path) to the photo gallery images. xmlName - The name of the XML file. xmlPath - This is the full file path of the XML file you will be using. This is the only tricky line. Some web hosts don't give read/write permission on directories accessible via the web server. This variable allows you to define a path to a folder that will permit writing and modifying files. Without such a folder this code won't work, so ask your web host for a read/write folder should this code fail.
<% 
' EXAMPLE PHOTO GALLERY SETUP 
key = "secret" 
' page password to access ADMIN 
galleryURL = "/pix/springbreak/" 
galleryASP = "default.asp" 
'this page 
galleryImageURL = "/pix/springbreak/images/" 
xmlName = "springbreak.xml" 
xmlPath = "c:\readwritefolder\" 
%>

Building the Photo Gallery

In addition to your choice of colors and layout, your photo gallery will make simple calls to functions in the galleryCode.asp file. These include:

backLink, nextLink - This will draw the HREF link to the previous and next image. The user can use a text or image link after the call. Be sure to close out the link with a </a>.

thisShort, thisLong - thisShort returns the assigned short title and thisLong returns the long description.

drawImage(border) - Make a call to this subroutine where you want the image placed. The parameter is the pixel width of the border.

drawSequence(perLine) - This returns a sequential list of all the images linked to a number. This allows the user to bypass using the Next and Previous navigation and jump directly to a particular image. The perLine parameter restricts the number of links per line.

drawAdmin - This call is where you want the Admin form to be placed on the page.

Overview

1 - Define filePaths and password on the top few lines of the gallery page.

2 - Upload gallery ASP page and gallerycode.asp file.

3 - Upload images to server. The directory should be unique to that photo gallery.

4 - View the page.

5 - If this the first time the page has been viewed, the images XML file will be created.

6 - Place the password in the querystring and then a FORM will display for each image.

7 - Update the title, description, and alt tag. Go the the next image; repeat this sequence until you've finished. NOTE: Verbiage is optional. However, you'll still want to go through each image so the image height and width are saved to the XML file.

Download

Download Photos2.zip (includes gallery.asp and galleryCode.asp) if you wish to run the ASP Photo Gallery.

Labels: , , ,

 

Restoring Civility To Your Browser (2002)

This article was written in 2002, but still holds a few valuable tips.

Back in 1998, surfing the Internet was less complicated. The user wasn't constantly bombarded with pop-up advertisements. Spyware or adware barely existed. And Flash was an exciting technology, not an invasion of noise and clutter on your browser. Today most users are hammered by pop-up windows, junk email, and most are unaware they have some form of adware or spyware installed on their system right now. Something went wrong, something went very wrong.

This article is not about how invasive advertising is ruining the surfing experience. You already know that. This is about taking back power from the advertising avalanche. The following steps are how you can restore some civility to your browser.

Eliminate Spyware and AdWare

Spyware and adware are little programs that get installed on your computer that monitor your Internet habits and bombard you with ads. I first learned about adware when I was surfing on Amazon.com. As soon as I arrived at the site, I saw a pop-up ad for a competing bookstore. Why would Amazon do such a thing? I poured through the source code of their document and realized they didn't. Something evil was lurking on my computer. After some investigation I discovered some freeware that I installed had placed an adware program on my machine. Getting rid of it wasn't easy.

Simplying uninstalling a piece of freeware with adware doesn't always remove it. Fortunately, the good people at LavaSoft have written a piece of software called Ad-Aware. According to their site: Ad-aware is a free multi spyware removal utility that scans your memory, registry and hard drives for known spyware and scumware components and lets you remove them safely.

Download this software and run it. It is wonderful.

Protect Yourself From Future Spyware and Adware

Before you download or run any new software, run a background check on it first. The word freeware used to mean that the author was some cool programmer sharing his or her work for free. Today it often means that the program has embedded code to toss ads all over your screen. Spy Checker is an on-line database that tracks which applications are adware or spyware. Go to SpyChecker.com before installing any software.

Who Do You Trust?

On Internet Explorer there is a section under Security called Trusted Sites. Go check and see if anything in there doesn't belong. If it doesn't, remove it. Many of you will see an AOL server listed. Whenever you install an AOL product (Instant Messenger or Netscape) the evil AOL-Time Warner adds itself to your IE trusted sites list. Get rid of it!

From an Information Week article:
When a user downloads or updates AIM, free.aol.com is added to the users' IE Trusted Sites Zone. This also happens if you download Netscape6.x with integrated AIM. It is one thing for them to put that free.aol.com link everywhere when you download N6, even in IE's bookmarks, but quite another thing to mess with security settings. Although mostly harmless, it is the principle. I don't think this is right. If this was Microsoft messing with a Netscape security setting, all hell would break loose.


Stop The Pop

There are countless pop-up window killers out there. Find one you like and use it. Surfing without a pop-up killer today is like driving without a seatbelt. For more products go to Download.com and search on pop-up.

Boycott the Bastards, Reward the Heroes

What sites do you surf frequently? Do the sites you visit practice aggressive advertising? When the Weather Channel started using Flash advertising, I stopped going there for my weather information. When Yahoo started using pop-up windows, I changed my home page to Google.com, which refuses to use pop-up ads.

Attacking the Senses

How many animated graphics (gifs) really enhance the surfing experience? Maybe 1%. The rest are annoying. And how about background sounds? If I choose to play an audio file that's great, but I don't want to give control of my speakers to some web site. Finally, have you ever exited a web page only see it delay and then do some weird color collapse? That's called a page transition. Fortunately, with Internet Explorer we can eliminate all 3 of these.

From Tools, select Internet Options, and then click the Advanced tab. Uncheck Enable Page Transitions. Then scroll down to the Multimedia section. From here you can uncheck Play Animations in Web pages, Play Sounds in Web Pages and even Play Videos in Web Pages. Doing these small steps will calm many of the annoying pixels dancing in your browser.

Conclusion

One of the topics I didn't cover due to it's complexities is ad-blocking. For those interested, read Blocking Ads with a Hosts File. Ad-blocking works by intercepting requests to popular ad web servers. The result is fewer banners and faster downloads.

Labels:

 

Creating an ASP Photo Gallery

This article was written in 2001. Although I wouldn't code a photo gallery this way today, it does demonstrate how it can be done easily in a Classic ASP.

I've never cared for traditional photo albums. They take up too much space, they reside in one location (unless copies are made), and after a few years go by they get buried in the attic. Digital photo galleries are far superior. Load up some pictures on some remote server, email out the URL, and presto you've got a photo gallery that people can access anytime they want. And no trips up to the attic.

Having a digital camera makes acquiring the photos easy, but constructing a new photo gallery every time you "shoot a roll of film" can be tedious and time consuming. What we need is a template that we can quickly upload the images and have the gallery operational in less than 30 minutes.

Prep the Pictures

Every digital camera is slightly different, but most generate an image that is too large and byte heavy for web viewing. So the first step is to reduce the size of the image and file. There are many tools that will do this. I use PhotoShop or ThumbNailer to create my photo galleries. If you've walked through the above example photo galleries you've probably noticed that all the images are the same size. This is by design. Having the images the same size allows the image to appear in the exact same spot on the screen as we traverse from image to image. It's also going to make our code easier. ThumbNailer can resize an entire folder on images with a single click.

Using your selcted graphic program, reduce the size of the images to the size you would like to use for the gallery. My 2 galleries use the dimensions of 400 width and 303 height. Reduce the size uniformily so the image doesn't appear stretched or squished. This is something the graphic program should be able to assist you with.

Name and Upload

This gallery is going to use numbers to keep track of the position of the gallery, so all images should be numerically named. Starting with "1", name the images: 1.jpg, 2.jpg, 3.jpg, etc. Make sure there are no gaps in the numbering sequence. For each gallery I build, I create a folder and then a sub-folder for the images. Once the folders are ready, FTP the files up.

Let's Code

Adding color, fonts, and logo graphics is something you can do on your own later. Let's get the gallery working first. This code can be dropped into the BODY of the .ASP file. The gallery definitions are at the top.

<% 
' define the number of pictures in your gallery, this will be the highest image number ex: 18.jpg 
numPix = 18 
imageWidth = 400 
imageHeight = 303 
' use the querystring to request the image 
pic = Request.QueryString("pic") 
' if this is the first page, default to picture 1 
If len(pic) = 0 Then pic = 1 
' build BACK functionality, I'm using an image called left.gif. 
If CINT(pic) = 1 Then     
   Response.Write "<a href=""default.asp?pic=" & numPix & """>" 
Else     
   prevPic = pic - 1     
   Response.Write "<a href=""default.asp?pic=" & prevPic & """>" 
End If 

Response.Write "<img src=""images/left.gif"" width=""40"" hspace=""10"" height=""30"" border=""0"" alt=""Go back""></a>"  
' draw selected image 
Response.Write "<img src=""images/" & pic & ".jpg"" width=""" & imageWidth & """ height=""" & imageHeight & """ vspace=""10"" alt=""photo"">" 
' build FORWARD functionality 
If CINT(pic) = numPix Then     
   Response.Write "<a href=""default.asp?pic=1"">" 
Else     
   nextPic = pic + 1     
   Response.Write "<a href=""default.asp?pic=" & nextPic & """>" 
End If 
Response.Write "<img src=""images/right.gif"" width=""40"" height=""30"" hspace=""10"" border=""0"" alt=""Next Photo""></a>" 
Response.Write "<br/>" 
' draw image number list below photo. This allows the user to jump around the gallery. 
For j= 1 to numPix    
 If j = CINT(pic) Then       
   Response.Write j & "  "    
 Else       
   Response.Write "<a href=""default.asp?pic=" & j & """>" & j & "</a> "    
 End If 
Next 
%>

Last Words

This is the down-and-dirty gallery that will work for most situations. In a future article, I'm going to build upon this gallery to add more features. In the meantime, go take some pictures.

Labels: , ,

 

Using ASPHttp To Scrape Data in Classic ASP

The article was written in 2001.

I recently discovered a cool ASP component from Server Objects called AspHTTP. This component allows an ASP page the ability to GET documents via the HTTP protocol. It also can POST data to a remote web page. Why would you need this for an ASP page? The ability to parse data off a web page and place it in your own format is one need. The AspHttp component lets you to pull the remote web page into your code as a string. From there you can use extensive string parsing to extract the data. Copyright Issues

Copyrights are outside the scope of this article. Just be aware that snagging someone else's data may make their legal departments unhappy. If you choose to use someone else's data, getting their permission may be a wise decision. Use this tool for good, not for evil.

Sample Code

<%
Set HttpObj = Server.CreateObject("AspHTTP.Conn") 
HTTPObj.Url = ' enter some URL here 
' fetch the HTML page into the strResult variable 
strResult = HTTPObj.GetURL 
' check for component error 
If Len(HTTPObj.Error) Then 
   Response.Write "ERROR: " & HTTPObj.Error 
Else ' did we retrieve a document? 
  intLength = Len(strResult) 
  If intLength > 0 Then 
    ' proceed with scrape 
  End If 
End If 
%>

Last Words

Data scraping can be an inexact science. If the web site changes their markup, you can find yourself recoding your scrape. Look for an API first before proceeding with a data scrape.

Labels: , ,

 

Building a Database Driven Table in Classic ASP Part 1

This article was written in 2001. The original title was Table Evolution 1 - The Basics

One of the most common tasks an ASP developer will do is populating an HTML table with data. In the years I've been doing ASP coding, I've created hundreds of tables. This article is the first part of a series demonstrating the evolution of moving data from the database to the screen. Before we can streamline the process, let's first understand the basics.

Three Steps

I've isolated three distinct steps to creating database-driven HTML tables.

1. Connecting to the database.

2. Getting a recordset.

3. Drawing the TABLE.

By separating each task, we will be able to reuse code and reduce the number of lines in our application. In the long run this will make your code easier to maintain.

Establishing a Database Connection

There should be one and only one place in your code where you establish a connection to a database. This means placing your connection code in an include file. Rewriting connection code on each ASP page that performs a database connection will come back to haunt you when the server name changes or your boss moves you from SQL Server to Oracle. Write this code once and if it needs updated, it can be done quickly without compromising the application.

Each database has a slightly different connection string. For this example, I'll be using a connection string to SQL Server. For more information on writing ADO connection strings read the article What's in an ADO Connection String? by John Peterson.
<% 
on error resume next 
' Create ADO Connection Object 
Set ac = Server.CreateObject("ADODB.Connection") 
' Build connection string and then Open connection
strSQL7 = "driver={sql server};server=mySQLServer;database=Northwind;uid=mas;pwd=secret" 
ac.Open strSQL7 
' Detect if there was an error connection to the database 
If err.number <> 0 Then 
  Response.Write "There was an error connecting to the database: " 
  Response.Write Err.number & " - " & Err.Description Response.End 
End If 
%>

Getting a RecordSet

There are several ways to get a recordset. You could use ADO to open up a table and then retrieve each field. You could even use a custom component to return a recordset. For this example we are going to use straight SQL.
<% 
sSQL = "SELECT CompanyName, ContactName, ContactTitle, City FROM Customers " 
Set rs = Server.CreateObject("ADODB.Recordset") 
Set rs = ac.Execute(sSQL) 
%> 

Drawing the TABLE

The Recordset holds all the information we need to draw the HTML table. In order to support code reuse, we will create a subroutine to draw the table in an include file.
Sub drawTable(rs, border, cellspacing, cellpadding, width, align) 
If NOT rs.EOF Then 
    Response.Write "<table width=""" & width & """ align=""" & align & """ border=""" & border & """ cellspacing=""" & cellspacing & """ cellpadding=""" & cellpadding & """>" & chr(10)
    Response.Write "<tr>" 
    For Each field In rs.Fields 
        Response.Write "<th>" & field.name & "</th>" 
    Next 
    Response.Write "</tr>" & chr(10) 
    '=== the altRow will allow us to set a different background color for alternate rows 
    altRow = FALSE 
    While NOT rs.EOF 
        If altRow = TRUE Then 
            Response.Write "<tr class=""altRow"">" 
        Else 
            Response.Write "<tr>" 
        End If 
        
        For each field in rs.Fields 
            thisValue = field.value 
            If len(thisValue) = 0 Then thisValue = " "         
            Response.Write "<td>" & thisValue & "</td>" 
        Next Response.Write "</tr>" & chr(10) 
        altRow = NOT altRow 
        rs.MoveNext 
    Wend 
    Response.Write "</table>" 
Else 
    Response.Write "<p>The query returned no data.</p>" 
End If 
End Sub

Last Words

The connection and drawTable code should be placed inside a single include file. Once that is done we can generate database-drive TABLES with a mere 6 lines of ASP code. I also recommend setting up a CSS file to customize the look of the TABLE. This code covers the basics. The Connection and Recordset have more methods and properties, but for this example we don't need them. In Part 2, we will improve upon the table with better column titles, paging and sorting.

Labels: , , ,

 

Photo and Classical Art Mashup

Today I saw a cool tutorial on how to merge the colors of classical paintings into photographs. Using Photoshop CS it is a very easy process. Load the painting and your photograph. Put your photo in focus and then select Image ... Adjustments ... Match Color from the toolbar. From the Source dropdown, select the painting and click OK. That's it. You're finished.

Montevideo, Uruguay Meets Renoir

The first photo is a building I photographed in Montevideo last summer. The second is a classic Renoir painting. And the third is the Photoshop mashup of the two. Montevideo Renoir Montevideo+Renoir

Buenos Aires Meets Matisse

After leaving Uruguay, I went to Argentina and took the first photo. The second image is a Matisse painting. And the third is their hybrid. Buenos Aires Matisse Buenos Aires+Matisse

Labels:

 

Override ReturnURL in ASP.NET Security

When using FormsAuthentication and a logged out user tries to enter a secured page that page name is appended to the ReturnUrl. After the user has been authenticated, the user is redirected to that page.

I had no problem with this feature until I timed out and hit my LogOff page. I wasn't authenticated to see the LogOff page, so it appended that page URL to the ReturnURL and sent me the LogOn page. Once I logged in, it redirected me back to the LogOff page, which promptly logged me out.

I decided it would be easier to pick the start page for the user, regardless of what the ReturnUrl parameter was. Instead of using FormsAuthentication.RedirectFromLoginPage, use FormsAuthentication.SetAuthCookie and handle the Redirect yourself.
if (FormsAuthentication.Authenticate(txtName.Text, txtPassword.Text))
{
    FormsAuthentication.SetAuthCookie(txtName.Text, true);
    Response.Redirect("MySecuredStartPage.aspx", true);              
}

Labels: , ,

 

Digital Colony Copyright © 1999-2008 XHTML   508
This site uses Blogger, which is not 100% XHTML compliant.
Try...Catch Disclaimer: For brevity many examples do not include error handling. That is your responsibility.