Monday, December 31, 2007

Maintaining Control Values Between Pages

Here is a quick example of how you can maintain the values of controls when switching back and forth between different web pages by making use of Session variables. You can use ASP.NET Session variables to pass the values from one web page to another, but if you need to return to the previous page via a button for example the web page will loose the previous values it had. You can maintain those values just as if you had clicked your browser's back button by using Session variables.

Below is a short example that demonstrates this.

Default.aspx
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="FNLabel" runat="server" Text="First Name"></asp:Label>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
<asp:Label ID="LNLabel" runat="server" Text="Last Name"></asp:Label><br />
<asp:TextBox ID="FNTextBox" runat="server"></asp:TextBox>
<asp:TextBox ID="LNTextBox" runat="server"></asp:TextBox>&nbsp;<br />
<br />
<asp:DropDownList ID="IncomeDropDownList" runat="server" AutoPostBack="True">
<asp:ListItem>10K -30K</asp:ListItem>
<asp:ListItem>31K - 50K</asp:ListItem>
<asp:ListItem>51K - 70K</asp:ListItem>
<asp:ListItem>71K - 90K</asp:ListItem>
<asp:ListItem>91K+</asp:ListItem>
</asp:DropDownList><br />
<br />
<asp:RadioButtonList ID="ResidenceRadioButtonList" runat="server" AutoPostBack="True">
<asp:ListItem>Apartment</asp:ListItem>
<asp:ListItem>Mobile Home</asp:ListItem>
<asp:ListItem>Townhouse</asp:ListItem>
<asp:ListItem>Single Family House</asp:ListItem>
</asp:RadioButtonList><br />
<asp:Calendar ID="AcctStartCalendar" runat="server" BackColor="White" BorderColor="#999999" CellPadding="4" DayNameFormat="Shortest" Font-Names="Verdana" Font-Size="8pt" ForeColor="Black" Height="180px" Width="200px">
<SelectedDayStyle BackColor="Green" Font-Bold="True" ForeColor="White" />
<TodayDayStyle BackColor="#CCCCCC" ForeColor="Black" />
<SelectorStyle BackColor="#CCCCCC" />
<WeekendDayStyle BackColor="#FFFFCC" />
<OtherMonthDayStyle ForeColor="#808080" />
<NextPrevStyle VerticalAlign="Bottom" />
<DayHeaderStyle BackColor="#CCCCCC" Font-Bold="True" Font-Size="7pt" />
<TitleStyle BackColor="#999999" BorderColor="Black" Font-Bold="True" />
</asp:Calendar>
<br />
<asp:Button ID="SubmitButton"
runat="server" OnClick="Button1_Click" Text="Submit" /></div>
<br />
</form>
</body>
</html>
Default.aspx.cs
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
LoadExistingValues();
}
protected void Button1_Click(object sender, EventArgs e)
{
Session["value1"] = FNTextBox.Text;
Session["value2"] = LNTextBox.Text;
Session["value3"] = IncomeDropDownList.SelectedValue;
Session["value4"] = ResidenceRadioButtonList.SelectedValue;
Session["value5"] = AcctStartCalendar.SelectedDate;

Response.Redirect("~/Page2.aspx");
}

private void LoadExistingValues()
{
if (!Page.IsPostBack)
{
if (Session["value1"] != null)
{
FNTextBox.Text = Session["value1"].ToString();
LNTextBox.Text = Session["value2"].ToString();
IncomeDropDownList.SelectedValue = Session["value3"].ToString();
ResidenceRadioButtonList.SelectedValue = Session["value4"].ToString();

AcctStartCalendar.SelectedDate = Convert.ToDateTime((Session["value5"]));
}
}
}
}
Page2.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Page2.aspx.cs" Inherits="Page2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="FNLabel" runat="server"></asp:Label>,
<asp:Label ID="LNLabel" runat="server"></asp:Label><br />
<br />
<asp:Label ID="IncomeLabel" runat="server"></asp:Label>
<br />
<asp:Label ID="ResidenceLabel" runat="server"></asp:Label><br />
<br />
<asp:Calendar ID="AcctSelectionCalendar" runat="server"></asp:Calendar>
<br />
<br />
&nbsp;
<asp:Button ID="PreButton" runat="server" OnClick="Button1_Click" Text="Return to previous page" /></div>
</form>
</body>
</html>
Page2.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class Page2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
FNLabel.Text = (Session["value1"]).ToString();
LNLabel.Text = (Session["value2"]).ToString();
IncomeLabel.Text = (Session["value3"]).ToString();
ResidenceLabel.Text = (Session["value4"]).ToString();
AcctSelectionCalendar.SelectedDate = Convert.ToDateTime((Session["value5"]));

}
protected void Button1_Click(object sender, EventArgs e)
{
Response.Redirect("~/Default.aspx", true);
}
}
This little example should show you how easy it is to maintain the values of controls when navigating back and forth between pages. I have not experimented extensively with other controls, so further tweaking may be required.



Wednesday, December 12, 2007

Running ASP.NET 2.0 in Integrated Mode on IIS 7

I just wanted to share this blog link that discusses the changes you'll need to be aware of when you running your ASP.NET 2.0 applications in Integrated Mode on IIS 7 on Vista or Windows Server 2008.

http://mvolo.com/blogs/serverside/archive/2007/12/08/IIS-7.0-Breaking-Changes-ASP.NET-2.0-applications-Integrated-mode.aspx

Friday, October 26, 2007

.NET Daily Tips

I stumbled across this website and thought I'd share it with everyone. Visit this site frequently for some little known tips you might not have ever known about regarding .NET

http://dotnettipoftheday.org/tips/

Tuesday, September 11, 2007

Resetting Visual Studio 2005 to Original Settings

NOTE: Issuing the following command will clear any custom and environmental settings.

You may come across a situation where your Visual Studio 2005 Environment is non-functional in one manner or another. This recently happened to me when I was trying to reset the environment to the General Environment settings using the Import and Export Settings Wizard. During the process I encountered an error which left the IDE in a state in which it would try to Initialize the Toolbox and after a few seconds close Visual Studio. Thus I was unable to access any of the ToolBox controls.

After a quick search I came across a command that you run from the Visual Studio Command Prompt to reset the IDE to its original install settings. If after exhausting all possible repair options you need to run this command please backup any custom and/or environmental settings you do not want to lose prior to its use.

Then perform the following:

1. Click Start and then select All Programs.
2. Select Microsoft Visual Studio 2005.
3. Select Visual Studio Tools and then Visual Studio 2005 Command Prompt.
4. Enter devenv /resetuserdata.

You will not receive any confirmation of reset completion, so you can use task manager to monitor the devenv process for its completion.

Friday, August 10, 2007

Symbols, Accents, Punctuation, and Foreign Characters

Have you ever needed to type special symbols or characters such as the Registered Trademark Symbol, Copyright Symbol, or perhaps an Umlaut or the Math Division Symbol in a document or web page? Trying to remember the codes that represent them or having to reference some web page that list them can be really impractical. There is a much easier way to access these symbols.

Many people are unaware of a small program that comes with Windows and Linux Distributions that provides them for you along with their associated codes. This same type of program I'm sure comes with OSX as well as other Operating Systems; however, I am unable to verify this due to my lack of access to the numerous number of Operating Systems available.

In Windows 2000/XP/Vista

1. Click the Start Button.
2. Select All Programs.
3. Select Accessories.
4. Select System Tools.
5. Select Character Map.

In Ubuntu Linux (Other Linux Distros may have similar steps)

1. Click Applications from the Task Bar.
2. Select Accessories.
3. Select Character Map.

Whenever you need to make use of a special symbol or foreign character just to mention a couple types; this is a very simple way that is readily available to you. No need to search for the codes for such symbols via the Internet or consult some other reference material.

Wednesday, July 25, 2007

Accessing Master Page Controls via Content Pages

There are a couple of ways to access the controls of Master Pages in ASP.NET 2.0 from within your content pages. You can do this in a non-strongly typed manner or a strongly type manner. I will provide a sample below that demonstrates each approach.

Non-Strongly Typed

Lets say your Master Page contains a Label that displays the current Date. Within your content page use the FindControl method to locate the control in the Master Page whose property you want to access. Note you must perform an explicit cast.

Label lbl = (Label)Master.FindControl("DateLabel");
lbl.Text = DateTime.Today.ToLongDateString();

Strongly Typed

In the code-behind of your Master Page create a property that accesses the control you want to manipulate.

public string GetCurrentDate
{
get { return DateLabel.Text; }
set { DateLabel.Text = value; }
}


In the HTML source of your content page add the following beneath the Page <%@ Page %><%@ Page %><%@ Page %>directive. Add MasterType before TypeName.


< typename="Site">

Replace "Site" with the class name of your Master Page. You could also re-write the above using VirtualPath in place of TypeName. NOTE: Blogger will not display the percent signs that are between the <> as well it also Strips out the MasterType Directive.

To do this just replace the MasterPage.master with the name of your Master Page.

Finally in the code-behind of your content page you can set the DateLabel to the current date on your Master Page as below:

this.Master.GetCurrentDate = DateTime.Today.ToLongDateString();

Thursday, July 12, 2007

Thursday, June 21, 2007

More Useful C# Code Snippets

Display Pop-Up Error Messages In An ASP.NET Application

I came across an issue in which someone needed to pop-up a Window to display an error message to users in their ASP.NET application. I did some research and discovered this very handy bit of code that will display a JavaScript Alert MessageBox that you can populate with the error message.

Below is an example I created that purposely causes a DivisonByZero Exception and displays this in a JavaScript Alert MessageBox.


int num1 = 10;
int num2 = 0;
int result;

try
{
result = n1 /n2;
}
catch (DivideByZeroException ex)
{
DisplayErrorMsg(ex);
}


private void DisplayErrorMsg(Exception ex)
{
RegisterStartupScript(Guid.NewGuid().ToString(),
string.Format("<script language='Javascript'>alert('{0}');</script>", ex.Message));
}

Populate The Display Text Of A CollapsiblePanel Control From A File

I had the need to populate the text to be displayed in an ASP.NET AJAX CollapsiblePanel Control via a text file as opposed to just embedding the text between a tag of my Content Panel. I had to display a large amount of text that displayed some Terms and Conditions and there was just to much to put between the tags. Besides it really would make the code ugly having all of that text embedded.

The solution I decided to go with was to create a Web User Control and fill the control with the text to be displayed. Then I went back to the page that I was going to display this text on and dropped the Custom Control inside of my CollapsiblePanel's ContentPanel. I then went into the HTML source of the page and surrounded the ContentPanel with a Div tag and sat the height, overflow, and background color.






<ajaxToolkit:CollapsiblePanelExtender ID="CollapsiblePanelExtender1" runat="server"
TargetControlID="ContentPanel"
ExpandControlID="TitlePanel"
CollapseControlID="TitlePanel"
Collapsed="false"
TextLabelID="Label1"
ExpandedText="(Hide Details...)"
CollapsedText="(Show Details)"
ImageControlID="Image1"
CollapsedImage="images/expand.jpg"
ExpandedImage="images/collapse.jpg"
SuppressPostBack="true">
</ajaxToolkit:CollapsiblePanelExtender>


<asp:Panel ID="TitlePanel" runat="server" Height="30px" Width="545px">
<asp:Image ID="Image1" runat="server" ImageUrl="~/images/expand.jpg"/>
Terms and Conditions
<asp:Label ID="Label1" runat="server" Text="Label">(Show Details ...)</asp:Label>
</asp:Panel>
<asp:Panel ID="ContentPanel" runat="server" Height="0px" Width="545px">                                
<div style="height:150px;overflow:scroll;background-color:ButtonFace;" >
<uc2:Terms ID="Terms1" runat="server" /></div>
</asp:Panel>

Friday, June 8, 2007

Useful C# Code Snippets

Mapping a month name to its chronological order value

The following C# code can be used to map a month name to its equivalent numeric chronological order value. You can use this code in a method and pass the month in as a string to convert for example "JUN" to 06. You can modify the array to map the full month name in place of it's three letter abbreviation.

public string MonthToNumberMapper(string month)
{
string Month = month.ToUpper();
string ConvertedMonth = null;
string[,] MonthsToConvert = new string[,]
{
{ "JAN", "01" }, { "FEB", "02" }, { "MAR", "03" }, { "APR", "04" },
{ "MAY", "05" }, { "JUN", "06" }, { "JUL", "07" }, { "AUG", "08" },
{ "SEP", "09" }, { "OCT", "10" }, { "NOV", "11" }, { "DEC", "12" }
};

// Determine the numeric month.
for (int i = 0; i < MonthsToConvert.Length / 2; i++)
{
if (Month == MonthsToConvert[i, 0])
{
ConvertedMonth = MonthsToConvert[i, 1];
break;
}
}

return ConvertedMonth;
}

Converting the text in a ComboBox Control to Uppercase
The following C# code can be placed in the TextChanged event handler of a ComboBox Control to change the case of the text entered to uppercase. This works for text entered into or selected within the ComboBox Control.

private void StateComboBox_TextChanged(object sender, EventArgs e)
{
String stateText = (string)StateComboBox.Text;
stateText = stateText.ToUpper();
StateComboBox.Text = stateText;
installStateComboBox.SelectionStart = installStateComboBox.Text.Length;
}

Saturday, June 2, 2007

Performing A Remote Registry Query To Display Installed Windows Updates

I received my first exposure to WMI(Windows Management Instrumentation) and accessing the Registry using C# when I worked on a personal project I came up with. I wanted to display the installed Windows Updates of Servers within a small network I created using VMware that consisted of a Domain Controller, a couple of additional Windows Servers, and a Windows XP Pro machine along with some additional information about the servers. I will show some sample code that demonstrates how to query a Remote Registry and retrieve a list of the installed updates in a Windows Application. NOTE: Your user account will need to be a member of the Domain Admins Group.

The first thing I did was to drop a ListView Control on an empty Windows form. I then configured a few properties such as setting the Form's size to a width of 450 and the ListView Control's Dock property to Fill. I added a few column headers to the ListView Control's Columns collection such as (Type, Description, Installed Date, and Installed By). Finally I set the ListView Control's View property to Details.

To query the registry remotely you will need to include a reference to the System.Management namespace and setup a couple of attributes to deal with Access Permissions to the registry as well as the Initial Hive location.

using System.Security.Permissions;

using System.Management;

using Microsoft.Win32;



[assembly: RegistryPermissionAttribute(SecurityAction.RequestMinimum, Read = @"HKEY_LocalMachine\SOFTWARE")]

[assembly: SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode = true)]

The SecurityAction.RequestMinimum requests a minimum group of permissions that is needed for the code to execute. Also the UnmanagedCode Parameter is set to true, because when working with the Registry you are dealing with Unmanaged code.

The ConnectionsOptions object contains the information needed to authenticate the user. Next a collection of WMI objects is returned after querying Win32_OperatingSystem from the Management classes.

string serverName = "192.168.239.128";



ConnectionOptions co = new ConnectionOptions();

co.Username = "username";

co.Password = "password";



ManagementScope ms = new ManagementScope("\\\\" + serverName + "\\root\\cimv2", co);

ObjectQuery objQuery = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");

ManagementObjectSearcher objSearcher = new ManagementObjectSearcher(ms, objQuery);

ManagementObjectCollection queryCollection = objSearcher.Get();

I perform a comparison on the OS Version number to display the proper registry information for a particular Windows OS. In this case it is for Windows 2000 and Windows 2003 Servers.

foreach (ManagementObject mo in queryCollection)

{

int ver = String.Compare(mo["Version"].ToString(), "5.2.3790");

if (ver == 0)

{

updateListView.Items.Clear();

RegistryKey win2003Key;

win2003Key = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, serverName).OpenSubKey("SOFTWARE").OpenSubKey("Microsoft").OpenSubKey("Updates").OpenSubKey("Windows Server 2003").OpenSubKey("SP2");

foreach (string subKeyName in win2003Key.GetSubKeyNames())

{

using (RegistryKey tempKey = win2003Key.OpenSubKey(subKeyName))

{

foreach (string valueName in tempKey.GetValueNames())

{

if (String.Equals(valueName, "Description"))

{

ListViewItem value = new ListViewItem(tempKey.GetValue("Type").ToString());

value.SubItems.Add(tempKey.GetValue(valueName).ToString());

value.SubItems.Add(tempKey.GetValue("InstalledDate").ToString());

value.SubItems.Add(tempKey.GetValue("InstalledBy").ToString());

updateListView.Items.AddRange(new ListViewItem[] { value });

}

}

}

}

}

else if (ver < 0)

{

updateListView.Items.Clear();

RegistryKey win2000Key;

win2000Key = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, serverName).OpenSubKey("SOFTWARE").OpenSubKey("Microsoft").OpenSubKey("Updates").OpenSubKey("Windows 2000").OpenSubKey("SP5");

foreach (string subKeyName in win2000Key.GetSubKeyNames())

{

using (RegistryKey tempKey = win2000Key.OpenSubKey(subKeyName))

{

foreach (string valueName in tempKey.GetValueNames())

{

if (String.Equals(valueName, "Description"))

{

ListViewItem value = new ListViewItem(tempKey.GetValue("Type").ToString());

value.SubItems.Add(tempKey.GetValue(valueName).ToString());

value.SubItems.Add(tempKey.GetValue("InstalledDate").ToString());

value.SubItems.Add(tempKey.GetValue("InstalledBy").ToString());

updateListView.Items.AddRange(new ListViewItem[] { value });

}

}

}

}

}

}

I drill down through the registry and retrieve the values for the updates populating the ListView Control with the name of the update, when it was installed, and who installed it.

This example has been based on a simple virtual network configured with Active Directory. In an actual network environment a few changes would have to be made depending upon the level of security imposed as well as any group policies in place and possibly other factors.





Tuesday, May 29, 2007

Caffeinated Drink Database

Have you ever wondered just how much caffeine is in a Red Bull drink or maybe in a Pepsi or Diet Coke? Well the people over at www.energyfield.com have created a large database that list many different drinks and the amount of caffeine they contain.

You might just be surprised at just how much caffeine you are getting. I have provided a direct link to their caffeine database below.

http://www.energyfiend.com/huge-caffeine-database/

Monday, May 21, 2007

How-To Shrink A VMWare Virtual Disk Image

Have you ever come across a situation where you needed to reduce the size of your VMWare Virtual Disk Image? I found various links via Google on how to expand the Virtual Disk Image size, but none on how to reduce its size. Well, I will show you how to shrink your VMWare Virtual Disk Image below using VMWare's FREE VMWare Converter software. NOTE: this process can also be done using Norton Ghost, but because I don't have it, I will only being showing how to do this using VMWare Converter.

As with any type of operation in which you stand to lose your data, make sure you have a good backup first. I've copied my Virtual Disk Image file into a temporary folder before performing these steps.


1. Choose Import Machine to start the VMWare Converter Import Wizard.









2. Select the option for Standalone virtual machine, backup or disk image. If the image is from ESX Server or VMWare VirtualCenter select the option ESX server or VirtualCenter virtual machine.

3. Select the image to be re-sized.













4. Click the drop-down arrow under New Disk Space and enter the new disk size for the image.







5. Choose the location to save the re-sized image to.












6. Choose where you will import this image to.












7. Select how the image will be created.













8. Choose how you want the image's NICs mapped.











9. Next you are able to perform some customizations on the new image if you choose. If you don't want to do this at this time just click Next.



10. The creation of the new image will begin, this process may take some time depending on what size you set for your new image.

11. Once the new image has been created I perform a shrink to reduce it to the size that it currently occupies with data.


That's all there is to shrinking a VMWare Virtual Disk Image to a new size.