Blogger Jeff = new Blogger

Programming and stuff in Western PA

ASP.Net Wizard Control

Have you ever had to ask a user to input a lot of information at once? Has one of your business requirements ever had you stagger your data input over a series of pages? Have you ever had a client insist on the ability to cycle through each one of those pages, and then display a summary at the end? Well then my friend, if you haven’t ever used ASP.Net’s Wizard control, then you’re missing all the fun.

What the Wizard control does is allow you to collect all the information you need in a series of steps. The control comes built in with functionality to cycle through each of your steps. In this post, we’re going to write a quick page, collecting two fields, add some form validation, and then displaying the results in a summary at the end.

First thing you need to do is add a web form to a project, and drag the Wizard control onto it. We’ll add an additional step to make our code look like:

<asp:Wizard ID="Wizard1" runat="server" >
    <WizardSteps>
        <asp:WizardStep runat="server" title="Step 1">
        </asp:WizardStep>
        <asp:WizardStep runat="server" title="Step 2">
        </asp:WizardStep>
        <asp:WizardStep runat="server" title="Summary">
        </asp:WizardStep>
    </WizardSteps>
</asp:Wizard>

What these three steps represent, of course, is a different step in our process. The Wizard control itself is derived from the View Control. We could accomplish these same steps with the View control, but would have to add a lot of what the Wizard control gives us (navigation from step to step,etc). If we run this now, we see what we get “out of the box” from our Wizard control :
Wizard Out of the Box

Let’s add the following to our code :

<asp:Wizard ID="Wizard1" runat="server" >
    <WizardSteps>
        <asp:WizardStep runat="server" title="Step 1">
            <asp:Label ID="lblFirstName" runat="server" Text="First Name" /> :
            <asp:TextBox ID="txtFirstName" runat="server" />
        </asp:WizardStep>
        <asp:WizardStep runat="server" title="Step 2">
            <asp:Label ID="lblState" runat="server" Text="State" /> :
            <asp:DropDownList ID="ddlState" runat="server">
                <asp:ListItem Text="Please select a state" Value="" />
                <asp:ListItem Text="PA" Value="PA" />
                <asp:ListItem Text="MD" Value="MD" />
                <asp:ListItem Text="DE" Value="DE" />
            </asp:DropDownList>
        </asp:WizardStep>
        <asp:WizardStep runat="server" title="Summary">
             <table border=1>
                <tr><td>First Name :</td><td><% Response.Write(txtFirstName.Text); %></td></tr>
                <tr><td>State :</td><td><% Response.Write(ddlState.SelectedValue); %></td></tr>
             </table>
        </asp:WizardStep>
    </WizardSteps>
</asp:Wizard>

This should be pretty self-explanatory, as we’ve added labels and controls to steps one and two, and then summary information to step three. If you run this, you can cycle through the steps, and the information, and get a summary at the end. You can also cycle back through and adjust the data as well. The final part missing is data validation. This too is easy to do, as all we have to do is add a validation summary control and whatever validation controls we need. We’ll do so, and adjust our now complete code to look like this :

<asp:ValidationSummary runat="server">
    </asp:ValidationSummary>
<asp:Wizard ID="Wizard1" runat="server" >

    <WizardSteps>
        <asp:WizardStep runat="server" title="Step 1">
            <asp:Label ID="lblFirstName" runat="server" Text="First Name" /> :
            <asp:TextBox ID="txtFirstName" runat="server" />
            <asp:RequiredFieldValidator ID="valFirstname" 
                runat="server" ErrorMessage="First Name is required" 
ControlToValidate="txtFirstName">*</asp:RequiredFieldValidator>
        </asp:WizardStep>
        <asp:WizardStep runat="server" title="Step 2">
            <asp:Label ID="lblState" runat="server" Text="State" /> :
            <asp:DropDownList ID="ddlState" runat="server">
                <asp:ListItem Text="Please select a state" Value="" />
                <asp:ListItem Text="PA" Value="PA" />
                <asp:ListItem Text="MD" Value="MD" />
                <asp:ListItem Text="DE" Value="DE" />
            </asp:DropDownList>
            <asp:RequiredFieldValidator ID="reqState" 
                runat="server" ErrorMessage="State is required" 
ControlToValidate="ddlState">*</asp:RequiredFieldValidator>
        </asp:WizardStep>
        <asp:WizardStep runat="server" title="Summary">
             <table border=1>
                <tr><td>First Name :</td><td><% Response.Write(txtFirstName.Text); %></td></tr>
                <tr><td>State :</td><td><% Response.Write(ddlState.SelectedValue); %></td></tr>
             </table>
        </asp:WizardStep>
    </WizardSteps>
</asp:Wizard>

Now if we try to skip to Step 2 without entering a name, we’ll see :
Wizard with validation

There you have it, a rather simple example that should get you on your way. The last part to this, once the Wizard is complete would be to save the contents to a data source.

Tags: ,

Advertisements

February 2, 2008 Posted by | ASP.Net, C# | 2 Comments

Using Linq to query a CSV File

I know there have been a ton of times I’ve had to deal directly with Comma Delimited files. Searching through the contents for certain pieces of data is usually not a whole lot of fun. However with Linq, things become a bit more enjoyable!

To start off, we’ll create a csv file with the following contents :

"Mets","New York","NL"
"Marlins","Florida","NL"
"Orioles","Baltimore","AL"
"Pirates","Pittsburgh","NL"
"Phillies","Philadelphia","NL"

Save that some place and name it “teams.csv”. Then we’ll add the following namespace to our class file :

using System.Data.OleDb

Then using OleDb, we can access the csv file, and load a data table into a data adapter :

String conn = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\;
    Extended Properties=""Text;HDR=No;FMT=Delimited""";

OleDbConnection cn = new OleDbConnection(conn);
OleDbCommand cmd = new OleDbCommand(@"SELECT * FROM C:\Temp\teams.csv", cn);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);

cn.Open();

DataTable dt = new DataTable();

da.Fill(dt);

At this point, we are good to go to query the datatable with Linq. Our entire function looks like this :

static void QueryCsv()
{

    OleDbConnection cn = new OleDbConnection (@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=
C:\;Extended Properties=""Text;HDR=No;FMT=Delimited""");
    OleDbCommand cmd = new OleDbCommand(@"SELECT * FROM C:\Temp\teams.csv", cn);
    OleDbDataAdapter da = new OleDbDataAdapter(cmd);

    cn.Open();

    DataTable dt = new DataTable();

    da.Fill(dt);

    var teams = from r in dt.AsEnumerable()
                where r.Field(2) == "NL"
                select new { City = r.Field(0), TeamName= r.Field(1) };

    foreach (var team in teams)
    {
        Console.WriteLine(String.Format("The {0} {1}",team.TeamName,team.City));
    }

    Console.ReadLine();

    cn.Close();

}

If you run this you should see :

Result Set

Now if your life is like mine, the client will always throw a screwball at you and say something like : “We need to return everything from the csv file where the record also exists in this other data source.” Linq makes this easy too. We’ll create a quick class to demonstrate to represent the other data source :

public class Mascot
{
    public string Name;
    public string City;
    public string Player;
}

We’ll then create a list with our data in it

List mlb = new List
{
    new Mascot{City="Philadelphia",Name="Philllies",Player="Cole Hammels"},
    new Mascot{City="Boston",Name="Red Sox",Player="Curt Schilling"},
    new Mascot{City="Florida",Name="Marlins",Player="Dontrelle Willis"},
    new Mascot{City="Cleveland",Name="Indians",Player="Jake Westbrook"},
    new Mascot{City="Baltimore",Name="Braves",Player="Eric Bedard"},
    new Mascot{City="Los Angeles",Name="Dodgers",Player="Randy Wolf"}
};

Adjusting our original code, we can query and join the two data sources to display some common data :

static void QueryCsvWithJoin()
{

	 String conn = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\;
	     Extended Properties=""Text;HDR=No;FMT=Delimited""";

	 List mlb = new List
	 {
	     new Mascot{City="Philadelphia",Name="Philllies",Player="Cole Hammels"},
	     new Mascot{City="Boston",Name="Red Sox",Player="Curt Schilling"},
	     new Mascot{City="Florida",Name="Marlins",Player="Dontrelle Willis"},
	     new Mascot{City="Cleveland",Name="Indians",Player="Jake Westbrook"},
	     new Mascot{City="Baltimore",Name="Braves",Player="Eric Bedard"},
	     new Mascot{City="Los Angeles",Name="Dodgers",Player="Randy Wolf"}
	 };

	 OleDbConnection cn = new OleDbConnection(conn);
	 OleDbCommand cmd = new OleDbCommand(@"SELECT * FROM C:\Temp\teams.csv", cn);
	 OleDbDataAdapter da = new OleDbDataAdapter(cmd);

	 cn.Open();

	 DataTable dt = new DataTable();

	 da.Fill(dt);

	 var teams = from r in dt.AsEnumerable()
	             join o in mlb on r.Field(1) equals o.City
	             where r.Field(2) == "NL"
	             select new { City = r.Field(0), TeamName= r.Field(1),Player=o.Player }; 

	 foreach (var team in teams)
	 {
	     Console.WriteLine(String.Format("Pitcher {0} from the {1} {2}", team.Player,team.TeamName, team.City));
	 }

	 Console.ReadLine();

	 cn.Close(); 

}

When run this, we get

Result Set 2

Tags: , , , ,

January 28, 2008 Posted by | .Net, C#, Linq | 14 Comments

Using Linq to query Xml

If you’ve used the .Net’s framework new Linq functionality, you’ve no doubt seen how nice it is to query a data object directly. For me, one of my favorite parts of Linq is being able to query an Xml object. Gone are the days are writing awkward XPath queries, or "ripping through" an Xml document.

Here’s the old school way of querying Xml :

static void OldSchool()
{ 
    string teams = @" " +
        "PhilliesNL" +
        "YankeesAL" +
        "AngelsAL" +
        "BrewersNL" +
        " ";

    XmlDocument xml = new XmlDocument();
    xml.LoadXml(teams);

    XmlNodeList NLTeams = xml.SelectNodes("//League[. = 'NL']/parent::node()/Name");

    foreach (XmlNode team in NLTeams)
        Console.WriteLine(team.InnerText);
}

And here’s the new school way :

static void NewSchool()
{
    XElement teams = XElement.Parse(@" " +
        "PhilliesNL" +
        "YankeesAL" +
        "AngelsAL" +
        "BrewersNL" +
        " ");
    
    IEnumerable NLTeams = from t in teams.Descendants("Team")
                   where t.Element("League").Value.Equals("NL")
                   select t.Element("Name").Value;

    foreach (var team in NLTeams)
        Console.WriteLine(team);
}

You’re pretty much writing the same amount of code, but the Linq way is more preferable in that it standardizes a way to query and object in .net for data.

Tags: , , ,

January 14, 2008 Posted by | .Net, C#, Linq, Technology, Xml | Leave a comment

C# 3.0 Extension Methods

C# 3.0 introduces a concept known as extension methods.  What these allow you to do is to "extend" static methods onto an existing instance class.  Trust me, it’s a lot easier to understand when seeing an example.  In mine, I’ll extend a FormatSSN method onto the string object :

class Program
{
    static void Main(string[] args)
    {
        String val = "987654321";
        Console.WriteLine(val.FormatSSN());
        Console.ReadLine();
    }
}

public static class Utilities
{
    public static String FormatSSN(this String input)
    {
        return String.Format("{0}-{1}-{2}", input.Substring(0, 3),
            input.Substring(3, 2), input.Substring(5, 4));
    }
}

Microsoft says "Extension methods are less discoverable and more limited in functionality than instance methods. For those reasons, it is recommended that extension methods be used sparingly and only in situations where instance methods are not feasible or possible."

So why would you ever want to use an extension method?  I would say for convenience purposes, like in the example above, perhaps you already have a pre-existing class and rather than go back and add a "FormatSSN" method, you could simply extend one to the current code base.

Tags: ,

December 1, 2007 Posted by | .Net, C# | Leave a comment

C# coalesce operator

Damn Microsoft! I finally thought I had my thick head wrapped around C# when they decide to come out with a boatload of new features to further confuse, err, I mean enhance things.

I was quite happy to read that they added a coalesce operator to C#. For those of you who use Sql Server on a regular basis, you’re probably quite familiar with this function. What it does is allow you to pass a list of values, and will return the first non-null value.

For instance, in previous versions of C# we might have code that looks like this :

After running this, the string “brian” gets outputted to the console. We can now rewrite this a little cleaner with the new coalesce (??) operator :

After running this, you’ll see we get the same results. Thanks again to the C# team for giving me the capability to make my code even more unreadable 😉

Tags: , ,

November 23, 2007 Posted by | .Net, C#, Technology | 3 Comments