How to apply UNIQUE constraints to existing SQL columns

I wanted to add this to my blog because I had some difficulty finding out (via Google) how to add a UNIQUE constraint to a SQL column that already existed. To bring you up to speed, UNIQUE constraints prevent duplicate row entries in a column.

Note: This pertains to Microsoft SQL Server 2000.

To add a UNIQUE constraint to a table column use the following SQL query.

ALTER TABLE [dbo].[UserProfile]
ADD CONSTRAINT [UniqueEmail]UNIQUE ([Email])

If you try to add a UNIQUE constraint to a column with duplicate rows SQL will throw an error. So clean up those duplicates first. Also, keep in mind that having unique rows means you cannot have duplicate NULL values.

To remove a UNIQUE constraint use the following SQL query.

ALTER TABLE [dbo].[UserProfile]
DROP CONSTRAINT [UniqueEmail]

Two Javascript Tricks: click() and trim()

Man my poor blog hasn’t been updated in quite some time. What on earth could I do to remedy that situation? Wait, I GOT IT! I’ll add a new post! šŸ™‚

Here are two really simple but really useful JavaScript tricks.

#1

document.getElementById(x).click();

The above is handy when you want to programmatically click a button for the user based on whatever logic you write. I used it to fire some ATLAS (now called ASP.Net AJAX) animations after I validated some fields.

#2

Add the following to your JavaScript library to trim the white space from the beginning and end of your strings.

String.prototype.trim=function()
{
	return this.replace(/^\s*|\s*$/g,'');
}

The above allows you to do this: xString = xString.trim();

Check out this Wikipedia article on ‘trim’. There are examples on how to trim a string for numerous programming languages.

http://en.wikipedia.org/wiki/Trim_(programming)

Extend Visual Studio 2005 DataSet Designer Using Partial Classes

One of my favorite features of Visual Studio 2005 is the easy to use DataSet designer. If you haven’t tried using the DataSet designer to create your data access layer try it out. Brian Noyes has written a nice tutorial here.

However, one issue I have with the DataSet designer is that it doesn’t give you the ability to create a SqlDataReader from the design interface. Fortunately there is a way around this limitation. Using partial classes you can extend the DataSet designer’s built in functionality to add your own methods. Brian Noyes touches on this in his tutorial I referenced above.

I have a little cheat to share that makes adding a SqlDataReader method to your TableAdapter a snap.

First off, you need to use the designer to create a TableAdapter. Have it create a GetData method for you.

Next you need to create a new class file for your project. I recommend naming it something like ‘<the name of your DataSet xsd file>Custom.cs’. That way itā€™s easy to identify.

Now you need to extend the namespace of your DataSet, and create a partial class for the TableAdapter.

Here comes the cheat.

Highlight the name of your TableAdapter you just created a partial class for. Right-click on it, and click on ā€œGo to Definition.ā€ This will take you to the Microsoft generated code for your TableAdapter. Below the definition code you should be able to find the ā€˜GetDataā€™ method. Copy that entire method block and retrofit it into the partial class you created for your SqlDataReader. Now simply replace the section of Microsoft generated code that creates and returns a DataTable with code that returns a SqlDataReader.

When youā€™re done youā€™ll end up with a class file that looks something like the following.

using System;
using System.Data;
using System.ComponentModel;
using System.Data.SqlClient;

namespace DataSetDirectTouchTableAdapters
{
    public partial class displayResponseQuestionTableAdapter : Component
    {

        public virtual SqlDataReader GetReader(System.Nullable ResponseSet, System.Nullable Question)
        {
            this.Adapter.SelectCommand = this.CommandCollection[0];
            if ((ResponseSet.HasValue == true))
            {
                this.Adapter.SelectCommand.Parameters[1].Value = ((int)(ResponseSet.Value));
            }
            else
            {
                this.Adapter.SelectCommand.Parameters[1].Value = System.DBNull.Value;
            }
            if ((Question.HasValue == true))
            {
                this.Adapter.SelectCommand.Parameters[2].Value = ((int)(Question.Value));
            }
            else
            {
                this.Adapter.SelectCommand.Parameters[2].Value = System.DBNull.Value;
            }
            this._connection.Open();
            return this.Adapter.SelectCommand.ExecuteReader(CommandBehavior.CloseConnection);
        }
    }
}

After you rebuild your project you can access the GetReader method via Intellisense! Good times. šŸ™‚

Workaround to IE's Overflow Auto and Position Relative Bug

The other day I ran into a rather annoying CSS bug in Internet Explorer 6 when using a XHTML strict or transitional doctypes. If you place a relatively positioned element inside of a container using overflow auto, the relatively positioned element becomes fixed on the page, rather than becoming visually contained in the overflow auto element.

IE Bug Example (HTML):

<div style="height:80px;overflow:auto;background-color:gray;width:200px;">
	<p style="position:relative;background-color:lightblue;width:150px;">
		I'm a relatively positioned element!
	</p>
	I am not.
</div>

IE Bug Example (In Action):

I’m a relatively positioned element!

I am not.

As stated by the W3C, this is not correct behavior.

9.4.3 Relative positioning

Once a box has been laid out according to the normal flow or floated, it may be shifted relative to this position. This is called relative positioning. Offsetting a box (B1) in this way has no effect on the box (B2) that follows: B2 is given a position as if B1 were not offset and B2 is not re-positioned after B1’s offset is applied. This implies that relative positioning may cause boxes to overlap. However, if relative positioning causes an ‘overflow:auto’ box to have overflow, the UA must allow the user to access this content, which, through the creation of scrollbars, may affect layout.

I believe I have discovered a workaround for this bug. IE will behave correctly if you add ‘position:relative’ to the containing element that is using ‘overflow:auto’. I believe this is an expectable workaround because setting ‘position:relative’ without setting the ‘top’ or ‘left’ attributes will not affect the page layout.

Solution Example (HTML):

<div style="position:relative;height:80px;overflow:auto;background-color:gray;width:200px;">
	<p style="position:relative;background-color:lightblue;width:150px;">
		I'm a relatively positioned element!
	</p>
	I am not.
</div>

Solution Example (In Action):

I’m a relativly positioned element!

I am not.

Let me hear from you if this helped you out.

How to submit HTML without disabling ValidateRequest

So the scenario is this. You have an ASP.Net form field that you want the user to submit HTML to the server with. By default ASP.Net won’t allow this for security reasons. You could get around this by setting ValidateRequest=”false” in the page declaration or in the web.config. But, if you are developing a user control, you don’t want to make the developer using your control have to manage this. Another reason may be that subsequent developers may not be aware that you’ve deliberately opened up a security hole that has to be managed. So, you want to keep ValidateRequest enabled, but how?

To do this I wrote a little ‘encodeMyHtml’ JavaScript function that is called on the OnClick event when the HTML formā€™s submit button is clicked. The function encodes the user’s HTML input for the field I’ve specified into a harmless string before it is passed to the server. When I receive that input on the server I simply decode and go on my way.

ValidateRequest is happy, our users are happy, our peers are happy, heck we’re happy.

I add my ‘encodeMyHtml’ JavaScript function in my user control’s OnPageLoad method. This way I can make sure that my JavaScript is added to the parent page only once, no matter how many controls are on the page.

In my controlā€™s OnPageLoad I call this:

private void addEditorJavaScript()
{
    // create our HTML encoder javascript function
    // this way it shows up once per page that the control is on
    string scr = @"<script type='text/javascript'>function encodeMyHtml(name){
                var content = document.getElementById(name).value
                content = content.replace(/</g,'<');
                content = content.replace(/>/g,'>');
                document.getElementById(name).value = content;
            }</script>";

    // add the javascript into the Page
    ClientScriptManager cm = Page.ClientScript;
    cm.RegisterClientScriptBlock(this.GetType(), "GlobalJavascript", scr);
}

In my controlā€™s ASPX Iā€™m using a gridview. I wrap the gridviewā€™s update asp:LinkButton in a span tag, and in that span tag I put my OnClickEvent.

<span onclick="encodeMyHtml('<%# UniqueID.Replace("$", "_") %>_FormViewContentManager_ContentTextBox')">
    <asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" CommandName="Update" Text="[Publish]" />
</span><span onclick="encodeMyHtml('  

When I get the input on the server side I simply call a couple of Replace methods on the input string to decode the HTML, and Iā€™m done.