January 2005 - Posts

Ever wanted to make a particular control on a page start out with the focus?  In the past, the only way to do this was to add some javascript to the OnLoad event on the Body tag.   Now, thanks to the DefaultFocus property, it is easy to set the focus.  Simply, specify which control is the default using the DefaultFocus property on the form tag.
 
<form id="Form1"
    defaultfocus="TextBox1"
    runat="server">
    <asp:textbox id="TextBox1"
      runat="server">
    </asp:textbox>
<form>
Here is something new about SQL Server 2005.  The varchar, nvarchar, and varbinary supports a max length.  Instead of being limited to 8000 characters in the past, this new data type supports up to 2GB of data.  No longer do you have to use text, ntext, and image data types.  In fact these data types have been marked for deprecation in the future.
Ok, this is probably got to be one of the coolest things that they have added that in not really talked about.  The form tag now supports a property called DefaultButton.  This property allows you to specify which button is clicked when the enter button is pressed.  Even cooler is that you can also specify this property on a panel.  Why this is cool is that on the home page we can have the LocationTime control submit to GetRates when the enter button is pressed.  At the same time, we could also have another textbox that submits to location search whenever the enter button is pressed.
 
Here is an example:
 
<Form id="Form1" runat="server" DefaultButton="GetRatesButton">
</Form>
This is another one of those new controls that inherits from WebControl instead of HtmlControl.  What's nice is that you can define hotspots just as you could with the original control, but you can specify whether the control navigates to a particular URL or it does a post back.   To determine what the control does set the HotSpotMode property to either Navigate or PostBack.   To have it go to a particular URL, set the NavigateUrl property.  When you are doing a postback, set the PostBackValue property (which works similarly to the CommandeName property of a button control).
 
Here is an example:
 
<asp:ImageMap id="MyImageMap" ImageUrl="Blah.jpg" hotspotmode="PostBack" OnClick="MyImageMap_Click" runat="server">
     <asp:RectagnleHotSpot top="0" left="0" bottom="50" right="50" postbackvalue="HotSpot1" />
     <asp:RectagnleHotSpot top="50" left="50" bottom="100" right="100" postbackvalue="HotSpot2" />
     <asp:CircleHotSpot" x="200" y="200" radius="25" hotspotmode="Navigate" NavigateUrl="/blah.aspx" />
</asp:ImageMap>
 
In this example, the fire RectangleHotSpot actually does a post back with a value of HotSpot1, and the CircleHotSpot navigates to a new url.  You can also create PolygonHotSpots
 
The event handling method handling the click event would look like this:
 
protected void MyImageMap_Clicked(Object sender, ImageMapEventArgs e)
{
    if (e.Value == "HotSpot1")
    {
         // do something
     }
     else if (e.Value == "HotSpot2")
     {
         // do something else
      }
}
 
As you can see this control is a lot more functional than in the past.
Has there ever been a situation where you wanted to bind a drop down list to a data source but also have a static item in there (i.e.: Pick One, Show All Cars, etc.)?  The AppendDataBoundItems property makes this a lot more simple.  Simply add your items at design time, make sure this property is true, and then also set your DataSourceId.  The static items you inserted will then not be overwritten when you bind the data to the control.
A new property has been added to the label control called AssociatedControlId.  This allows you to link a label to another control on the page.  This is useful for linking to textboxes, dropdownlists, etc.  When this property is set, focus is automatically set to the associated control whenever the label is clicked.
One new feature added to the textbox control is the ability to specify custom auto complete sources for textboxes (for browsers that support autocomplete of course).  By creating an AutoCompleteStringCollection, which is just a simple collection, and by binding it to the AutoCompleteCustomSource property of the textbox you can specify where the browser pulls its autocomplete list from.  In order to do this you must also set the AutoCompleteSource property to CustomSource.  You can also specify any of the builtin sources such as AllUrl, FileSystem, HistoryList, etc.  This could prove to be a useful feature for internal applications.
Since i missed a day this week, I thought I would throw in a bonus tip.  There is now a FileUpload control.  You don't have to use the HtmlInputFile control any more.   This new control actually inherits from the WebControl class as opposed to the HtmlControl class.   Check it out the next time you need to do some file uploading.
I'll be talking more and more about some of the less hyped features in ASP.NET 2.0.  The Button control has three new properties.  OnClientClick can be used to specify a javascript method to invoke when the button is clicked.  Yeah, it could do this before, but now intellisense won't freak out when previously you tried to use OnClick.   PostBackUrl can be used to post your data to a different page.  UseSubmitBehavior causes the button to emit JavaScript to perform a post (similar to LinkButton controls).
UPDATE:  I touched on this earlier, but if you want to see a real working sample, go to:
 
 
The Search By Id textbox is in a different validation group than the rest of the search criteria.  Therefore, you can submit a search without filling out the ErrorIdTextBox.  The items are in SourceSafe in the 2.0 branch if you are interested.
 
I think most people have heard of ValidationGroups by now, but I wanted to touch on it, just to make sure.   Many times in the past, there were situations where you had multiple forms on the page that needed to be validated seperately from one another.  A good example is our index page with the Location / Time control and a Location Search textbox.  Today, without special handling, typing something in the location search textbox will cause all of the Location / Time control validators to fire.  This is obviously not the intended behavior.
 
Now a new property has been added to button controls as well as validators called ValidationGroup.  Simply set this property to the same name for all controls that you want to be validated together.  Set a different name for the other controls on your page that you want to be evaluated seperately.  So in the above example, all of the Location / Time control's controls and validators would set ValidationGroup equal to LocationTime.  The Location Search controls could be set to LocationSearch.
 
Here is a quick example of how two different sets of textboxes and butons can be validated seperately:
 
    <asp:TextBox
        id="TextBox1"
        Runat="Server" />
    <asp:Button
        ValidationGroup="Group1"
        Text="Submit"
        OnClick="Group1Click"
        Runat="Server" />
    <asp:RequiredFieldValidator
        ValidationGroup="Group1"
        ControlToValidate="TextBox1"
        Text="(required)"
        Runat="Server" />
   <asp:TextBox
        id="TextBox2"
        Runat="Server" />
    <asp:Button
        ValidationGroup="Group2"
        Text="Submit"
        OnClick="Group2Click"
        Runat="Server" />
    <asp:RequiredFieldValidator
        ValidationGroup="Group2"
        ControlToValidate="TextBox2"
        Text="(required)"
        Runat="Server" />

Like I said, many of you have probably already heard of this feature, but I thought it was worth covering again.
ASP.NET 2.0 offers a variety of compilation options.  As of Beta 2, Web sites can be compiled just like they are in 1.1 (i.e.: binaries with aspx pages left untouched).   As you know, in ASP.NET 1.1, the first time you go to a web page in an application, there is a delay while the Framework compiles the IL code.  In 2.0, this delay can be removed for a customer by going to precompile.axd off of your web application's root.  Going to this URL will simply return a message that says your application has been precompiled successfully (provided there is nothing wrong with your application of course).  Now, the first customer to go to your site will not have to experience any delay visiting the site.
 
ASP.NET applications can aslo be precompiled using the Publish Web Site menu option in Visual Studio 2005.  Using that option, will compile the entire web site (inclucing aspx and ascx files) into a single group of binaries.  This allows the entire site to tbe deployed by moving the bin folder.  This option obviously has its limitations since it could never work with Rhythmyx.  Note: precompile.axd can not be used when you compile with this method, because the application is already precompiled.
How many times have you typed something like <%# DataBinder.Eval(Container.DataItem, "VehicleType") %>?  Some of you may have already read this, but now you can replace the above with <%# Eval("VehicleType") %>.  This may not be terribly exciting, but it should make your lives easier when trying to remember syntax. 
 
As a side note, the Visual Studio 2005 IDE now has improved Intellisense inside the markup window, so these kinds of methods will actually show up.
Quite a few new features have been addded to SQL Server 2005 in the Transact-SQL area.  Take a look at this article which goes over some of them.
 
One of the new features of ASP.NET 2.0 that I you may have heard about is role providers.  Out of the box there is a Sql Role Provider and a Windows Token Role provider (the access one was removed from beta 2).  You can also of course create your own by doing some inheritance (i.e.: Blue Chip Role Provider). 
 
The role provider you are using is configured in the web.config.  I would include some sample code, but I am pretty sure they changed the entire syntax for configuring it and I am yet to figure it out using the CTPs. 
 
What I am going to talk about today is more about the Roles (System.Web.Security) class and NTLM.  There are also numerous controls that make use of roles, that I will touch on at some point in the future.
 
When using ntlm authentication, the roles class can prove to be quite useful.  It has several member methods that will allow you to determine if the user belongs in a particular Windows NT security group, etc.  This is a lot easier than in the past where you had to use ADSI objects (which basically just used Interop). 
 
The two methods that may be of use when using NTLM are IsUserInRole() and GetRolesForUser().    IsUserInRole will tell you if a user is in a particular Windows NT security group (i.e.: DTG\WWWThrifty).  GetRolesForUser can be used to troubleshoot access issues by returning an array of roles that the user belongs to.
 
An example of GetRolesForUser can be viewed at:
 
This is only a handful of the methods that this class has.  There are a lot more methods that you can use when using a SqlRoleProvider.  These other methods allow you to add users to roles, create new roles, configure the cookie that the roles are stored in, etc.  I'll touch on these more in the future.
One of the new features of ASP.NET 2.0 that is less talked about is the health monitoring system.  It allows you log things like failed logins, unhandled exceptions, expired forms authentication tickets, etc.  The new health monitoring system is provider based so you can have it log to the event log or to a sql server out of the box.  Of course you can always create your own provider as well.
 
To create a custom web event, simply create a new class and inherit from WebBaseEvent.  For example, if you wanted to log an event every time a button was clicked (for example, Get a Rate, or Make Reservation), create a class that looks like this.
 
using System;
using System.Web.Management;
 
public class MakeReservationWebEvent : WebBaseEvent
{
     DateTime clickDateTime;
 
     public MakeReservationWebEvent(string message, object source, int eventCode, DateTime myDateTime) : base(message, source, eventCode)
     {
          // assign to classwide variable
          clickDateTime = myDateTime;
     }
 
     // override this method to specify which text is logged
     public override void FormatCustomEventDetails(WebEventFormatter webEventFormatter)
     {
          // log a custom message
          webEventFormatter.AppendLine("Clicked at: " + clickDateTime.ToString());
      }
}
 
Once you have created your custom web event class, you simply need to register it in your machine.config/web.config.
 
<healthMonitoring enable="true">
     <eventMappings>
          <add name="Make Reservation Events" type="MyWebEvent, __code" />
     </eventMappings>
     <rules>
            <!-- log to event log, could also specify SqlWebEeventProvider -->
           <add name="Make Reservation Events" eventName="Make Reservation Events" provider="EventLogProvider" />
     </rules>
</healthMonitoring>
 
Firing the custom event is not as straight forward as you would think.  First you must instantiate your web event and raise it with the base class.  You would put the following in your click event handler:
 
// instantiate your custom web event
MakeReservationWebEvent makeReservationWebEvent = new MakeReservationWebEvent("Reservation Made", null, 101, DateTime.Now);
 
// raise the event to be logged
WebBaseEvent.Raise(makeReservationWebEvent);
 
I think custom web events will prove to be quite powerful and I can see them logging all types of useful information in our applications in the future.
More Posts Next page »