Skip to main content
Select a theme:
   
RSS Feed

Visual Studio Team System 2005 December CTP Released

The latest build has been released and it can be downloaded through MSDN.  I am currently downloading it if anyone wants to install it.  This should be the most feature complete version released to date.  I'll post more on it as I evaluate it.

Expression Handlers

Expression handlers in ASP.NET 2.0 are similar to the previous data handling declarative syntax; <%# DataBinder.Eval ( .. ) %>.   You can now access various elements out of your web.config or resources files by using these expressions in your markup.
 
For example, if you need access to a connection string names LocationConnectionString, you would simply type (remember from yesterday, connection strings are in their own section of the web.config):
 
<%$ connectionstrings: LocationConnectionString %>
 
This is typically used in things like SqlDataSources.
 
To access something in the appSettings element, you just do:
 
<%$ appSettings: MyKey %>
 
Resources files have been extended greatly and they may actually pose a viable solution for multilingual text management now.  So they can now be used in things like labels, textboxs, etc.
 
For example:
<asp:label id="MyLabel" runat="server" text="<%$ resources: MyKey %>" />
 
If these expression handles don't provide you with what you need, then you can always write your own.  Although, I am not exactly sure how to do that yet.

Configuration API

The configuration API has been expanded greatly to allow for new features such as writing and encryption.  In the past, doing these tasks were not convenient at all but now they are relatively easy.  The web.config has many new sections as you will come to find out.  A new <connectionStrings/> section has been added specifically for connection strings.  
 
Encrypting your connectionStrings now is easy.  Simply write a page to do the initial encryption.
 
// get an instance of the configuration object
Configuration configuration = Configuration.GetWebConfiguration(Request.ApplicationPath);
 
// get the connection strings section
ConnectionStringsSection connectionStringsSection = configuration.ConnectionStrings;
 
// encrypt using DPAPI
connectionStringsSection.ProtectSection("DataProtectionConfigurationProvider");
 
// update the web.config
configuration.Update();
 
To access your encrypted connections strings, you don't have to do a thing.  Instead of using the AppSettings property, just use the Configuration.ConnectionStrings

BONUS TIP! Compiling v1.1 assemblies with Visual Studio 2005

This is something that we learned in a session at Visual Studio Connections.  The person that lead the session finally posted how to do it on his site.  This really won't work for ASP.NET applications, but it will work for class libraries and things of that nature.
 

New Development Features in SQL Server 2005

Ok, by now you have probably heard of at least some of the new features that will be added with the new version of SQL Server.  A lot of theses changes allow you to do things on a SQL Server that you could have never done before.  Some of the biggest changes that have been added come from CLR intergation.  This gives you things like .NET Stored Procedures, .NET User Defined Functions, Extended Triggers, and .NET user defined types.  On the ADO.NET side, new things have been added such as Multiple Active ResultSets, asynchronous support, and paging support. 
 
Alright, a lot of buzz words have been mentioned today and I am not going to go into defining them at this time.  However, I encourage to go this URL and read some of the sample chapters. 
 
 
The chapter even has some sample code of a lot of the new features and is worth the read.

Beta 2 Changes

I have installed the Novemeber CTP on a virtual machine which already has some of the changes included in Beta 2.  The entire software installs like it is Beta 2 (i.e.: the text everywhere in the product says Beta 2).  The framework version is 2.0.41202.
 
Aside from the compiler directives and directory changes that Microsoft has notified us of (also discussed in the announcements), there are numerous other changes.  The first thing I noticed is that there is actually a start page now.  It automatically pulls a list of recent projects and displays headlines from MSDN.  I am not sure if any of this is configurable yet.
 
I am attempting to migrate an existing application from Beta 1 and here is what I have noticed so far.  The names of all of the providers have changed (i.e.: WindowsTokenRoleProvider is now AspNetWindowsTokenRoleProvider).  The other thing that appears to have happened is that all the attributes used to define a custom profile provider have changed. 
 
Unfortuanately, there is no MSDN help in this build.  An installer happens to be sitting on the disc image but when you try to install it, it tells you that .NET Framework Beta 2 is required.  My guess is that it was built with a different build of the framework.  An update to Visual SourceSafe is also included but I could not get its installer to run either.
 
Any how, I am currently unable to get my application working because there is no help available for setting up the parameters in the web.config and intellisense doesn't really give me enough information to help either.  This is normally something that you could simply use the ASP.NET Configuration pages (WebAdmin.axd) to set up, but unfortunately I couldn't get those pages to run either.  I eventually did get this to run on a simple new application, but for some reason there was no profile provider listed.
 
In summary, this build seems very preliminary, but it is good to see that they are making progress.

Native FTP Support

Some of you already know that the .NET Framework v2.0 supports FTP, so this may not be new to all of you.  The FtpWebRequest class makes it easy to upload and download files to an FTP server. 
 
The class functions similarly to the HttpWebRequest class.
You open a connection by using WebRequest.Create()
 
// create a new request and cast it to ftp
FtpWebRequest ftpWebRequest = (FtpWebRequest)WebRequest.Create(serverUri);
// set the credentials
ftpWebRequest.Credentials = new NetworkCredential ("anonymous","blah@blah.com");

Strangely enough, the example I have seen uses the DownloadData() method to download a file, but this method is mentioned nowhere in the documentation.  So I have no idea if it works or not.  If anyone tries it, please let me know.

byte [] newFileData = request.DownloadData (serverUri.ToString());

The FtpWebRequest class also supports most typical ftp operations.  Secure FTP can be enabled by setting the EnableSsl property to true.  Passive mode can be enabled by setting Passive to true.
 
In turn the FtpWebResponse class can be used to get the status, banner message, etc.

Threading made easy with the BackGroundWorker Class

The BackGroundWorker class makes it easy to execute an operation on a seperate, dedicated thread.  In the past, creating new threads for simple background operations could prove to be quite troublesome.  The BackGroundWorker class makes it easy. 
 
To set up a BackGroundWorker simply add an event handler for the DoWork event.  You can put your long, time-consuming operations inside that event.  When you are ready to start the operation, simply call the RunWorkerAsync method.  The ProgressChanged event can be used to notify your application of any progress that has occurred.  Lastly, the RunWorkerCompleted method will fire when the operation has completed.
 
// Set up the BackgroundWorker object by 
// attaching event handlers
protected void InitializeBackgoundWorker()
{
    backgroundWorker1.DoWork +=
                new DoWorkEventHandler(backgroundWorker1_DoWork);
    backgroundWorker1.RunWorkerCompleted += 
                new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
 }
 
// launch the aync process on a button click event
protected void Button_Click(System.Object sender, System.EventArgs e)
{
     // start the async process
     backgroundWorker1.RunAsync();
}
 
// perform the long operation
protected void backgroundWorker1_DoWork(object sender,
            DoWorkEventArgs e)
{
    // do something
    DoSomething();
}
 
// work completed event
protected void backgroundWorker1_RunWorkerCompleted(
            object sender, RunWorkerCompletedEventArgs e)
{
     // display completed message
     ShowWorkCompletedMessage();
}
 
For more information, take a look at:
ms-help://MS.VSCC.v80/MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.VisualStudio.v80.en/cpref/html/T_System_ComponentModel_BackgroundWorker.htm

MultiView Control

The MultiView control is a container for a group of View controls.  What the MultiView control is good for is creating multistep processes.  Each view control can contain a series of controls that you create.  Use the ActiveViewIndex property can be used to set which view is currently being displayed.  Only one view at a time can be displayed, but this can be a great way to implment multistep processes where you previously used panels.
 
For more information:
ms-help://MS.VSCC.v80/MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.VisualStudio.v80.en/cpref/html/T_System_Web_UI_WebControls_MultiView.htm
 

FormView Control

By now, most of you have heard about the new GridView control and stuff like that.  However, the new FormView control allows you to quickly create the ability to display and edit data while giving you full control of your HTML markup.
 
The FormView control binds to a DataSource control just like the GridView.  The beauty of a FormView control is that when you bind it to a typed dataset or whatever using a datasource control.  It will automatically generate a template for displaying and editing items from that datasource.
 
For example, I didn't have to type any of the code below.  All I did was drag and drop an ObjectDataSource control and a FormView control in the designer.  I used the menu to configure the data source and bind the formview to that data source.
 
<asp:FormView ID="FormView1" Runat="server" DataSourceID="ObjectDataSource1">
    <EditItemTemplate>
        CarModelId:
        <asp:TextBox Text='<%# Bind("CarModelId") %>' Runat="server" ID="CarModelIdTextBox"></asp:TextBox><br />
        ImageFileName:
        <asp:TextBox Text='<%# Bind("ImageFileName") %>' Runat="server" ID="ImageFileNameTextBox"></asp:TextBox><br />
        ThumbnailImageFileName:
        <asp:TextBox Text='<%# Bind("ThumbnailImageFileName") %>' Runat="server" ID="ThumbnailImageFileNameTextBox"></asp:TextBox><br />
        LuggageCount:
        <asp:TextBox Text='<%# Bind("LuggageCount") %>' Runat="server" ID="LuggageCountTextBox"></asp:TextBox><br />
        PassengerCount:
        <asp:TextBox Text='<%# Bind("PassengerCount") %>' Runat="server" ID="PassengerCountTextBox"></asp:TextBox><br />
        Description:
        <asp:TextBox Text='<%# Bind("Description") %>' Runat="server" ID="DescriptionTextBox"></asp:TextBox><br />
        MatchedBy:
    </EditItemTemplate>
    <ItemTemplate>
        CarModelId:
        <asp:Label Text='<%# Bind("CarModelId") %>' Runat="server" ID="CarModelIdLabel">
        </asp:Label><br />
        ImageFileName:
        <asp:Label Text='<%# Bind("ImageFileName") %>' Runat="server" ID="ImageFileNameLabel">
        </asp:Label><br />
        ThumbnailImageFileName:
        <asp:Label Text='<%# Bind("ThumbnailImageFileName") %>' Runat="server" ID="ThumbnailImageFileNameLabel">
        </asp:Label><br />
        LuggageCount:
        <asp:Label Text='<%# Bind("LuggageCount") %>' Runat="server" ID="LuggageCountLabel">
        </asp:Label><br />
        PassengerCount:
        <asp:Label Text='<%# Bind("PassengerCount") %>' Runat="server" ID="PassengerCountLabel">
        </asp:Label><br />
        Description:
        <asp:Label Text='<%# Bind("Description") %>' Runat="server" ID="DescriptionLabel">
        </asp:Label><br />
    </ItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="ObjectDataSource1" Runat="server" TypeName="Thrifty.Components.Web.Locations.Resources.Locations"
    SelectMethod="GetFleetByLocationCode">
    <SelectParameters>
        <asp:Parameter Type="String" Name="locationCode"></asp:Parameter>
    </SelectParameters>
</asp:ObjectDataSource>
 
The FormView control has various templates but the two it autogenerates are ItemTemplate and EditItemTemplate.  ItemTemplate displays the data and EditItemTemplate provides a means to edit the items.  This control can easily be used in conjunction with the GridView control to provide a master/details data editor. 
 
This means that creating simple data editors that used to take several hours can probably now be done in a manner of minutes.

Visual Basic .NET MyServices Namespace

While the C# team was working on thing of <del>no-importance</del> great importance like generics, the VB.NET team has worked diligently on creating a new series of classes called the My Classes.  These classes provide a series of basic functionality that provide features for everything from logging, getting computer information, playing sounds, and opening serial ports.
 
All the methods are considered static when used through Visual Basic.  Here is an example of how to play a WAV file using Visual Basic .NET.
 
My.Computer.Audio.Play("c:\Windows\Media\chimes.wav")
 
Some of the other classes available are: MyClock, MyComputer, MyComputerInfo, MyLog (huh huh), MyNetwork, and MyPrinters.  The MyComputer class hosts properties including FileSystem, Keyboard, Moouse, Registry, and Screen.  The MyComputerInfo class provides properties to get information such as the MachineName, OSVersion, Physical Memory, etc.
 
Now don't run out and switch to VB just yet (sorry, Marcus).  These classes are available in the Microsoft.VisualBasic.MyServices namespace.  To get access to that namespace, just add a reference to Microsoft.VisualBasic.dll.
 
Here is the above example in C#.
 
// instantiate myAudio object
MyAudio myAudio = new MyAudio();
 
// play a wav file
myAudio.Play("C:\\WINDOWS\\Media\\Chimes.wav");
 
In C#, the only extra step you have to take is to instantiate the object first.  The MyServices namespace is worth exploring because they make a lot of taks that sometimes took a bit of code really simple.
 

File.ReadAll() and File.WriteAll()

Ever wanted to open a file and store it in a string and not worry about having to deal with streams and all that crap?  Well now you can with File.ReadAll and File.WriteAll.  The ReadAll method will open a file, read the entire contents into a string, and then close the file.
 
// read the entire contents of the file into a string
string fileString = File.ReadAll("ReservationLabels_en-US.xml");
 
The WriteAll method crates a new file, writes the contents of the string to the file and then closes the file.  If the file already exists, it is overwritten.
 
// write the entire contents of the string into the file
File.WriteAll("ReservationLabels_en-US.xml", fileString);
 
If you need a little more control of the file, you can use the File.ReadAllLines() and File.WriteAllLines methods.  These methods do the same thing as the previous methods except that each line is stored as a different element in a string array.
 
// read entire file into an array of strings
string fileStringArray[] = File.ReadAllLines("ReservationLabels_en-US.xml");
 
If you are working with binary files, you can use the File.ReadAllBytes() and File.WriteAllBytes() methods to read the contents of the file into a byte array.
 
Although working with files has never been terribly difficult, this certainly makes dealing with files in these situations even easier.

Nullable Type

Tired of object referece is null errors?  The new Nullable<T> generic type is here to make your life easier.  In continuing our discussion with generics from yesterday, this new type allows you to have value types which accept null values.
 
Here are couple of examples of Nullable declarations:
Nullable<int> x = 123;
Nullable<int> y = null;

Both lines are ok and will not throw an exception.
 
There are many ways you can access the type safely.
 
To check if the type has a value (i.e. not null), simply use the HasValue property.
 
// check to see if x has  a value
if (x.HasValue)
{
    int myInt = x.Value;
}
 
Or you can access it safely using the static GetValueOrDefault(Nullable<T>) method:
 
int myInt = Nullable.GetValueOrDefault(y);
 
The above method will return the default value for the alue type int (in this case 0).
 
I believe the Nullable<T> type will prove to be quite valueable, especially when doing data access.

BONUS TIP! Configuring IIS After Installing .NET Framework 2.0 Beta 1

Most people have experienced this by now, but I am going to go ahead and document it.  After installing the .NET Framework 2.0 Beta 1, all of your web applications are configured to run using version 2.0 of the framework.  When you try to run any of your existing 1.1 applications using a browser, more often than not you are going to get a yellow screen, or a server application unavailable error message.  If you have event logging turned on, you will probably either see a message elaborating more on the above or one of your controls might give you an error like "DataSource and DataSourceId are both defined on this control.".
 
For the most part, this is easy to fix.  Simply tell your web applications to run using ASP.NET 1.1 again.  In the past you usually just used aspnet_regiis -i out of the v1.1 folder.  However, ASP.NET 2.0 added a new ASP.NET tab in IIS on your web site's properties.  Simply, click on the tab and choose v1.1.  You may need to do this on every web instance and web application on your server or machine.
 
Running multiple versions of the Framework on the same web instance
Some times it may be necessary to run one particular web application inside an instance on a different version of the framework.  Typically how you do this is you create the application in IIS and choose v2.0 on the ASP.NET tab.  However, when you run the application, you get an error.  If you check the event log it will tell you that you can not run two version of the framework inside the same application pool.
 
To resolve this, open up Application Pools inside IIS and add a new application pool.  Call it something like ASP.NET 2.0 Application Pool.  Then edit the web application that you created and choose the new application pool you created.  Make sure all of the other web applications on the site are using a different application pool (i.e.: Default Application Pool). 
 
At this point, it almost always requires a restart of IIS.  Once you do that, all of your applications should run.
 
 

Dictionary object

Some of this stuff you may have already heard about, but I thought I would touch on some stuff regarding generics.  The dictionary object is an object that can take many different data types for both it's key and value.
 
Here is example of how one is declared:
 
Dictionary<string, VehicleDataSet> vehicleDataSetDictionary = new Dictionary<string, VehicleDataSet>();
 
In this case a string is the key (i.e.: PickupLocationCode) and it is taking a typed dataset as a value.
 
Before you might have had to do something like this to retrieve data:
 
int CarModelId = ((VehicleDataSet) vehicleDataSetHashTable["LAX"]).CarModelId;
 
That's a bad time.
 
The dictionary object will let you use retrieve an item from the dictionary without boxing.
 
int carModelId = vehicleDataSetDictionary["LAX"].CarModelId;
 
Notice, that there is no casting required.
 
Note: If you want to verify that the key is valid before accessing an item in the dictionary object, simply use the ContainsKey() method.  This is necessary otherwise you will throw an exception.
 
if (vehicleDataSetDictionary.ContainsKey(locationCode))
   return vehicleDataSetDictionary[locationCode];
 
Lastly there are a ton of new generic collections available in the System.Collections.Generics namespace: List, LinkedList, Queue, SortedDictionary, Stack, etc.

String.IsNullOrEmpty()

How many times have you written a statement like this?
 
if ( (myString != null) && (myString != string.Empty) )
 
Often as a developer you have to check for both null and empty.  But now thanks to the new property IsNullOrEmpty() on the String object, you can check for both null or empty at the same time.  Just think of how much code you won't have to write now.
 
The above line would look like this:
 
if (String.IsNullOrEmpty(myString))
 
That is so much easier.

WinFX Avalon SDK CTP Released

This really isn't a tip but I thought it was worth posting.  The Avalon (Microsoft's next generation Presentation Subsystem) SDK CTP has been released.  If you have VS2005 installed and Windows XP Service Pack 2, you can install this add-on to Visual Studio.  Once it is installed, you will have the option to create Avalon applications in addition to Windows Forms Applications.
 
Avalon uses XAML, a new markup language, for rendering controls etc.  Once Longhorn is released, this will allow for Vector Based graphics, etc.
 
Here is an example of what a XAML application looks like.
 
<DockPanel xmlns="http://schemas.microsoft.com/2003/xaml">
    <Border Background="LightBlue"
            DockPanel.Dock="Top">
        <Text>Some Text</Text>
    </Border>
   
    <Border DockPanel.Dock="Bottom"
            Background="LightYellow">
        <Text>Some text at the bottom of the page.</Text>
    </Border>
   
    <Border DockPanel.Dock="Left"
            Background="Lavender">
        <Text>Some more text</Text>
    </Border>
   
    <Border DockPanel.Dock="Fill">
        <DockPanel>
            <Button DockPanel.Dock="Top"
                    Height="30px"
                    Width="100px"
                    Margin="10,10,10,10">Button1</Button>
            <Button DockPanel.Dock="Top"
                    Height="30px"
                    Width="100px"
                    Margin="10,10,10,10">Button2</Button>
            <Border DockPanel.Dock="Fill"
                    Background="LightGreen">
                <Text >Some Text Below the Buttons</Text>
            </Border>
        </DockPanel>
    </Border>
</DockPanel>

One thing interesting about XAML applications is that they can be viewed as a stand-alone application or through a browser.
 
As a side note, it looks like some Indigo templates snuck into this add-on: Indigo Messaging Framework Client, Indigo Service Framework Service, Indigo Messaging Framework Service.  I am not sure if these are functional at all so if anyone tries them, let us know.

StopWatch Class

The StopWatch class is kind of a neat new class which lets you time things in a manner similar to a stop watch.  There was no simple way to time things in ASP.NET other than to keep tracks of Ticks and a start time, etc.  Now, to time how long something takes simply instantiate the StopWatch class and call the Start() method.  When you are finished timing simply call the Stop() method.  To get the time elapsed, access the Elapsed property.  This property will return a TimeSpan which you can use to get any sort of unit of time that you are interested in.
 
Here is a simple code example:
 
// instantiate the stopWatch
StopWatch stopWatch = new StopWatch();
 
// start the stopWatch
stopWatch.Start();
 
// do something that you want to time the duration of
 
// stop the stopWatch
stopWatch.Stop();
 
// get the time elapsed
TimeSpan timeSpan = stopWatch.Elapsed;
 
This class is not terribly exciting but it will make things like Average Time Performance Counters a little easier to implement.  This class is located in System.Diagnostics.

TryParse() is a good time

Ever needed to see if a string contained a date or int?  In .NET 1.1, about the only way to do this is to use DateTime.Parse() and see if it throws an exception.  That's a bad time.
 
Now thanks to TryParse(), you can check and see if the input is valid, before parsing.  This prevents the need for using a try/catch block every time you use the parse method.
 
The syntax is kind of wierd so this method can be called in two ways:
 
Method 1:
string dateTimeString = "12/23/2004 09:00 AM";
DateTime myDateTime;
 
// returns true if dateTimeString is valid
if (DateTime.TryParse(dateTimeString, myDateTime))
    myDateTime = DateTime.Parse(dateTimeString);
 
You can also get the DateTime directly from an output parameter.
Method 2:
 
string dateTimeString = "12/23/2004 09:00 AM";
DateTime myDateTime;
 
DateTime.TryParse(dateTimeString, out myDateTime);
 
It can also be used for ints, bytes, chars, doubles, bools, etc. 
 
i.e.:
int32.TryParse(intString, myInt);
bool.TryParse(boolString, myBool);
 
It's a simple feature, but I think it will prove to be useful in the future.
 
More information can be found here:
ms-help://MS.VSCC.v80/MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.VisualStudio.v80.en/cpref/html/M_System_DateTime_TryParse_2_c11ce641.htm

NOTE: This site is migrating to DotNetMafia. For the latest tips on Visual Studio 2008, SharePoint, and MOSS, see Corey's .NET Tip of the Day.