|
 Thursday, March 29, 2007

ASP.NET HOWTO: Enable Default Enter Button in ASP.NET 2.0

In certain forms, such as search forms, users enter a value into the search query box, then press the enter button. If you are develolping in ASP.NET, the page will refresh, but nothing will happen. The buttons click event wont fire... UNLESS, you explicity enable a default enter button on the form.

A problem that existed in ASP.NET 1.x was that you could not specify a default enter button unless you provided some custom code. In ASP.NET 2.0 you can do this very easily, unfortunately its not that widely used, much less known.

HOW TO:

The HtmlForm object has a property DefaultButton. This property gets or sets the control that that causes the post back when the ENTER key is pressed.

Example

<body>
   <form id="form1" runat="server" defaultbutton="processRequestButton">
      <div>
         <asp:TextBox AccessKey="c" runat="server" ID="somevalueTextbox"></asp:TextBox>
         <asp:Button runat="server" ID="processRequestButton" Text="Process" OnClick="processRequestButton_Click" />
      </div>
   </form>
</body>

Result

When the user presses the ENTER key, the form will be posted back and the processRequestButton_Click event will be fired.

Simple!

kick it on DotNetKicks.com
#    Comments [4] |
 Tuesday, March 27, 2007

Overcomplicating simple things - ASP.NET AJAX Confirmation Button Extender

Web 2.0, the big hit. Its everywhere, everyone is doing it. Microsoft has made it very easy for us developers to implment some very cool features of AJAX through the ASP.NET Ajax.NET framework. Simply install, drag and drop and deploy, blammo, you're done.

But there in lies the problem. What about developers who take this for granted? This turns our profession into a melting pot of people who think they can code but actually can't do much of anything other than drag and drop. I'm talking about the developers who implement this type of solution and run with it. They have no concern about how it works, why it works the way it does, it just solves the problem. Little did they know, they went through more work getting this done than is required. Continue on...

Introducing the ASP.NET AJAX Confirmation Button Extender...

This extender enhances usability by giving the user a choice of what to do. For example...

I'm all for ease of use, but sometimes even the smartest people can complicate something VERY SIMPLE. We've all suffered from Analysis Paralysis at one point in our career and well, I think the Confirmation Button Extender is a product of that symptom.

Why would I want to use the AJAX>NET framework to implement a simple confirmation box when I could use the OnClientClick with a fraction of the code?

Here's what I'm saying.

AJAX.NET Implementation

<asp:LinkButton runat="server" id="LinkButton1" Text="test" />

<ajaxToolkit:ConfirmButtonExtender ID="cbe" runat="server"
TargetControlID="LinkButton1"
ConfirmText="Are you sure you want to click this?" />

ASP.NET Implementation with JavaScript:

<asp:LinkButton runat="server" ID="testButton" OnClientClick="return confirm('Are you sure you want to click this?');" Text="test" />

These two methods DO THE EXACT same thing. Yes, the markup output is different, but honeslty, the latter of the two is much easier to implement. To implement this in AJAX.NET you have include the dll and js files, blah blah blah.

The problem I have with the AJAX.NET implementation is that its not helping me gain anything. I have to type more code to get the same thing accomplished. I see this as teaching developers its ok to lean heavily on the design time . This is a problem that we've been solving for years in web dev. How to send a confirmation to a user, and it seems, just now, a lot of people are just figuring it out due to AJAX.NET and they think its "the only way", mainly because ... well ... it worked from a drag/drop perspective. Unfortunately it takes more code than necessary and when the developer finally figures out what it does, they usually say "well why did Microsoft implement it that way? This is soo much eaiser doing by using OnClientClick".

My answer: "So you could get it to work, quickly. If developers cant figure it out on their own, then its time abstract the problem out into another level, and thats exactly what they did. Removed the knowledge of how and why, and replaced it with an easy to implement solution."

We call them R.A.D. Tools and sometimes in this industry its a love/hate relationship with them. :)

 

#    Comments [0] |
 Monday, March 26, 2007

error CS0030: Cannot convert type (Login.master)

I ran into an interesting error today and for a minute I didnt understand why it occurred.

Exception
c:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files\exampleapp\571e5472\336672e2\App_Web_login.master.cdcab7d2.gh4qw4cs.0.cs(115): error CS0030: Cannot convert type 'ASP.login_master' to 'System.Web.UI.WebControls.Login'
http://localhost/exampleapp/login.aspx?ReturnUrl=/exampleapp/default.aspx
/exampleapp/login.aspx


The site ran fine when running under the local cassini web web server but when we pre-compiled the website through our continuous integration system and then dropped it on our test server, everything went hay-wire. This error started popping up.

After a few moments of reviewing the error I figured it out.

The problem

The master page code behind class was called "Login". ASP.NET 2.0 also has a class by the name of Login. The .NET Framework was trying to convert one type (the master page type) to the actual Login class type.

The Fix

You can fix this one of two ways.

1. Give the full type name in the inherits attribute of the master page.

      e.g.: NameSpace.Type

2. Change the code behind class name from "Login" to something like "LoginMaster".

 

Conclusion

As I found (after the fact of solving this) Rahul Soni to say ... "dont give a class the name of 'Login'".

Please note, I've also see this problem with class names that are of the following:

  • Error
  • View
  • Wizard

I'm sure there are more, but these are the ones I've see cause this problem before.

 

 

#    Comments [1] |

IIS 7 - This configuration section cannot be used at this path.

If you're new to IIS 7 (you probably are) you might receive this nice little gem when you first start working with it:

HTTP Error 500.19 - Internal Server Error
Description: The requested page cannot be accessed because the related configuration data for the page is invalid.
Error Code: 0x80070021
Notification: BeginRequest
Module: IIS Web Core
Requested URL: http://localhost:80/ExampleApplication/
Physical Path: C:\inetpub\wwwroot\ExampleApplication\
Logon User: Not yet determined
Logon Method: Not yet determined
Handler: Not yet determined
Config Error: This configuration section cannot be used at this path. This happens when the section is locked at a parent level. Locking is either by default (overrideModeDefault="Deny"), or set explicitly by a location tag with overrideMode="Deny" or the legacy allowOverride="false".
FONT color=#a52a2a>
Config File: \\?\C:\inetpub\wwwroot\ExampleApplication\web.config
Config Source:
  184: 		</modules>
  185: 		<handlers>
  186: 			<remove name="WebServiceHandlerFactory-Integrated"/>

IIS 7 implements "Configuration Locking". This is to help with IIS administration. The IIS Administrator can lock down Configuration Sections, Section Elements and Attributes at the IIS level. This allows the administrator to have a more granular level of control on the system. Read this link to see more about it.

Important Note:  In order make these changes, you must be an administrator on the machine where the config file resides. If its on your local machine, you must be an administrator on your machine. 

Since I'm on my own development machine, and since this is a development machine, I have decided to change the global setting (the config section itselft). To fix this error I had to go to the applicaitonHost.config file and set the overrideModeDefault to "Allow".

Here's how:

Open the applicationHost.config file, located here: %windir%\system32\inetsrv\config\applicationHost.config

In my instance, I need to edit the "handlers" section.

Change this line:

<section name="handlers" overrideModeDefault="Deny" />

To:

<section name="handlers" overrideModeDefault="Allow" />

Thats it. :)


You might receive more errors after you enable this, such as the same error for modules, but just follow the same steps above, and you should be good.

Note: You can accomplish this same thing through the command line by using the appcmd.exe application (%windir%\system32\inetsrv\appcmd.exe). Like this:

%windir%\system32\inetsrv\appcmd unlock config -section:system.webServer/handlers

One more note...

This is not something you'd want to do on a production server unless you're sure you want to enable all appliations to override the section contents. Be sure to read up on some of the docs (explanation of the configuration system) before you make this change on production.

#    Comments [6] |
 Thursday, March 22, 2007

Using Excel to help with Data formatting (SQL Scripts)

(Download Excel Spreadsheet example at the bottom.)

Sometimes when developing I need to work with data. Sometimes this data is from external sources such as other partners in the business. Unfortunately when I get this data does not follow a consistent format therefore I'm left with formatting it for entry into a data store, usually a SQL Server.

In my last post about how to create store locator, I had this same problem. I had to import a list of company addresses for that tutorial. The only place I knew where to get a good list of locations for a store locator would be off of Starbucks Store Locator site. Through the trusty copy/paste method, I was able to grab about 200 store results in a matter of minutes from the website.

Now back to the original problem, the data format. The data looked like this after is was copied...

1. 1385 Metropolitan Ave (UCO)
1385 Metropolitan Avenue
Bronx NY, 10462
United States

I needed it to look like this (for ease of use, plus its easier to debug):

1385 Metropolitan Ave (UCO)
1385 Metropolitan Avenue
Bronx
NY
10462
 
Which will finally transform into this:

INSERT INTO dbo.Locations(LocationName, Address, City, State, Zip) VALUES ('1385 Metropolitan Ave (UCO)', '1385 Metropolitan Avenue', 'Bronx', 'NY', '10462')

Hmmm... problem. Now I could take my time, write an SQL insert script for each and every one of these, but that would take forever.

Instead we can use Excel to do this for us.

First off, all credit for this sweet little trick goes to Chris Lawson (a developer I worked with during my time at Todd McFarlane Producitons, SPAWN.COM). He's the one who showed it to me, I'm just showing it to you. :)

To get the data formatted into SQL insert scripts we need to use a few functions from Excel. We'll mainly use LEFT, MID, RIGHT, TRIM and SEARCH. Using those 4 methods you can pretty much get anything you want out of the string, and thats what I've done.

Note: It might be very helpful if you downloaded my sample at the bottom of this post and read this while looking at the sample, just so you can see how it was done.

Step 1: Separate the Data

We're going to want to take our data from this format:

1. 1385 Metropolitan Ave (UCO)
1385 Metropolitan Avenue
Bronx NY, 10462

and organize it to:
 
1385 Metropolitan Ave (UCO)
1385 Metropolitan Avenue
Bronx
NY
10462

Which will eventually get transformed into SQL, like this ...

INSERT INTO dbo.Locations(LocationName, Address, City, State, Zip) VALUES ('92nd & 3rd', '1642 Third Avenue', 'New York', 'NY', '101283618')


a) Get the Title to look like: 1385 Metropolitan Ave (UCO)

Tasks:
 - Get rid of the "1. " 

This will return the text in A1 without "1. " in it.


This takes the contents in cell A1 (the text with the 1. 1385 Metro...) and gets rid of the 1. through some simple text manipulation. The SEARCH method takes a parameter to search for. Utilizing the single character wildcard "?" I'm able to find where the numbering 'ends' and then get the text after that utilizing the LEN and RIGHT functions.

I'm going to use the same method for each line...
 

Address


 

City


 

State


Zip


Step 2. - Creating the SQL

Now that we have all the fields separated, we can easily create a SQL Script off of this.
Simply concatinate them together.

(click for larger view)


Now that we have all of this done, we can copy, and paste the this code (or click and drag the bottom right corner) throughout the sheet.
This will create the fields and SQL for us.

Then, two lines down...

Which gives us...


Now, select the entire "C" COLUMN and copy it ...

 

Now move that to any column down the line from column "C", lets say, "E". Right click and click "Paste Special"


 

Then click "Values"

 

Step 3 - Extracting the SQL

Now all the actual text values will be placed into the columns. You can now select Column "E" and copy all of those values.

The reason we have to paste special is because otherwise we'd be copying the column caluculations, instead of a pretty SQL script, we'd get a row with no data, such as:

INSERT INTO dbo.Locations(LocationName, Address, City, State, Zip) VALUES ('', '', '', '', '')

By pasting special, we're telling Excel we want the VALUES of the cells, not the actual calculations.

Now that you've "pasted as special" with values, you can now copy column "E" and then paste that into your SQL Management Studio and run. For simplicity sake, here are a few rows from the actual Excel file that is attached to this post.

INSERT INTO dbo.Locations(LocationName, Address, City, State, Zip) VALUES ('1385 Metropolitan Ave (UCO)', '1385 Metropolitan Avenue', 'Bronx', 'NY', '10462')
INSERT INTO dbo.Locations(LocationName, Address, City, State, Zip) VALUES ('Whitestone', '138-11 20th Avenue', 'Whitestone', 'NY', '113562451')
INSERT INTO dbo.Locations(LocationName, Address, City, State, Zip) VALUES ('Target Flushing T-1150', '13505 20th Ave', 'Flushing', 'NY', '11356')
INSERT INTO dbo.Locations(LocationName, Address, City, State, Zip) VALUES ('LGA - Delta Flight Ctr-Delta Term', 'La Guardia International Airport', 'Flushing', NY', '11371')
INSERT INTO dbo.Locations(LocationName, Address, City, State, Zip) VALUES ('Flushing - Main Street', '41-02 Main Street', 'Flushing', 'NY', '11372')

Then execute your script and you're on your way.


Conclusion

When is it appropiate to use this method? IT DEPENDS. If you have 10 records, no. If you have 1000 records? Yes. Its all about productivity. Ask yourself, is it going to be faster for me to spend 5 minutes writing this in EXCEL or is it going to take me 5 minutes to import them manually? This is up to you to answer. Hopefully this helps you on your next project. :)

Download File

starbucks-locations-xls.zip (52.71 KB)

kick it on DotNetKicks.com
#    Comments [0] |