Home Page
"Join my free Amazing ASP.NET newsletter"
It's safe and easy to signup. You get:
  • Notified anytime a new article comes out
  • Technical step-by-step tutorials on all important ASP.NET topics
  • Expert guidance so you can reach unlimited ASP.NET success
  • Important ASP.NET news updates
Enter your Email

Since last year, Microsoft has been creating videos and releasing other preview materials about the upcoming .NET Framework 4.0 release.  The new release is going to contain CSharp C# 4.0 and Microsoft will also release the newest version of their IDE which is going to be called Visual Studio 2010 (big surprise right?).  In this article I’m going to glance over some of the key new features in the .NET Framework 4.0.  I’m excited that there is new stuff just around the corner.

One of the most notable enhancements in .NET 4.0 is the new version of CSharp C# 4.0.  According to Microsoft, C# 4.0 will emphasize dynamic programming.  You will be able to dynamically instantiate and interact with objects which adds flexibility and code simplification in certain circumstances.  You will be able to pass parameters to methods by name instead of having to pass by position.  You will be able to declare default parameter values for methods.  You will be able to program with generics in an easier fashion and with more flexibility.  That can especially prove useful when using LINQ for database programming since generics are involved with LINQ.  There are also some COM Interop enhancement features in C# for dealing with COM interfaces like the Microsoft Office Automation APIs.

Another cool new enhancement that will ship with .NET 4.0 is Velocity.  Velocity is an enhanced and scalable caching framework for applications and it offers:

  • Distributed caching using clusters
  • Session support without the need for a back-end database

Velocity is going to be really useful for web applications that have a high volume of users and are hosted in web farms.

Here are some additional new improvements in the .NET Framework 4.0:

  • Microsoft says that Windows Communication Foundation will also see enhancements to help improve application messaging and enterprise application programming.
  • JQuery has been added to the ASP.NET Ajax client tools that will ship with Visual Studio 2010.
  • There is a new language created called FSharp F#.  FSharp F# started as a research project but was liked so much that Microsoft decided to formally make it part of the .NET Framework 4.0.

Stay tuned for my next set of articles where I will be discussing the improvements in CSharp C# 4.0 and Visual Studio 2010.  What would you like to see in the new .NET Framework 4.0?

Category: Advanced ASP.NET

Click here to download the web service project source code.
Click here to download the web service client project source code.

In this lesson I am going to teach you how to update an ASP.NET C# application that uses a web service whenever there are changes to the web service application.  In the previous lessons of this category, I had created an ASP.NET web service that retrieves data from a database table and returns the list in a web service method named getCustomers().  I had also created an ASP.NET client web application that calls and uses the web service to display a list of data on a web form.

There may be situations where you want or need to make modifications to the back-end web service that your web application is calling.  In fact, when you are developing an ASP.NET C# application that has a web service tier, you may be making frequent updates to the web service back-end during the development process.

Examples of updates to the back-end web service that I are applicable to this lesson are:

  • Changing the web service method signature (e.g. adding new parameters to a web service method or changing the return type of a web service method)
  • Adding a new web service method
  • Removing an existing web service method
  • Renaming an existing web service method

All of these types of updates mentioned above can require that a client application become aware of the changes.  In fact, if you change something like a web service method signature and you don’t update (or refresh) an ASP.NET web service client application to reflect the changes, you could end up with both compile time and runtime errors.  I will show you examples of these types of errors in this lesson so that you can fix the problems if they arise during your own web service and client application development process.

There are also situations where you DON’T have to update (or refresh) an ASP.NET web service client application if the back-end web service changes.  Here is an example:

  • You changed the logic in a web service method, but the method signature did NOT change.  In other words the method still returns the same type and expects the same parameters.

Now let’s get to the actual lesson.  I am going to describe what I did in a step by step fashion.  I had a back-end web service named Lab18_csharpuniversity_webservice that contained a class named CustomerData, with a method named getCustomers():

[WebMethod]
public string getCustomers()
{
 SqlDataAdapter dbadapter = null;
 DataSet returnDS = new DataSet();

 using (SqlConnection dbconn = new SqlConnection(
     "Server=localhost;"
     + "Database=csharpuniversity;"
     + "User ID=sa;"
     + "Password=Sqlserverpass$123;"
     + "Trusted_Connection=False;"))
 {
     SqlCommand cmd = new SqlCommand();
     string sqlQuery = "select * from customer";

     cmd.CommandText = sqlQuery;
     cmd.Connection = dbconn;
     dbadapter = new SqlDataAdapter(cmd);

     dbadapter.Fill(returnDS);
 }

 return returnDS.GetXml();
}

getCustomers() queries the database and returns a list of customers in an XML string.  Let’s say that I had a requirement to make this method a little bit more dynamic and give it the capability of performing a search based on the customer’s last name.  Due to this new requirement, I added a string parameter named pLastName to the method.  Then I added the database search code inside the method by using an SqlParameter object.  I added a query parameter named @last_name and then put that in the SqlCommand parameters collection so that the query will use it.  Here is what the updated version of the method looked like:

[WebMethod]
public string getCustomers(string pLastName)
{
        SqlDataAdapter dbadapter = null;
        DataSet returnDS = new DataSet();

        using (SqlConnection dbconn = new SqlConnection(
            "Server=localhost;"
            + "Database=csharpuniversity;"
            + "User ID=sa;"
            + "Password=Sqlserverpass$123;"
            + "Trusted_Connection=False;"))
        {
            SqlCommand cmd = new SqlCommand();
            SqlParameter param;
            string sqlQuery = "select * from customer ";

            if (pLastName.Length > 0)
            {
                sqlQuery += "where last_name = @last_name";

                param = cmd.CreateParameter();
                param.DbType = System.Data.DbType.String;
                param.ParameterName = "@last_name";
                param.Value = pLastName;
                cmd.Parameters.Add(param);
            }

            cmd.CommandText = sqlQuery;
            cmd.Connection = dbconn;
            dbadapter = new SqlDataAdapter(cmd);

            dbadapter.Fill(returnDS);
        }

        return returnDS.GetXml();
}

Now that this method was updated, I was able to test my web service with Visual Web Developer and make sure that it works.  I tested by executing the web service method both with and without a last name input argument value.  If a last name is not supplied, the method was supposed to return all of the customers in the database.  Click here to watch a video that shows what web service changes I made and shows how I tested the web service after the code changed.  Notice that when I supplied a last name value, only the records that match that last name were returned by the web service.

Since this update changed the method signature of getCustomers() in the back-end web service, it qualifies as one of the reasons that you would have to update (or refresh) an ASP.NET client web application.  Remember the bullets that I had at the beginning of this lesson.  Let’s explore what happens if you don’t update the files in the ASP.NET client web application.

Before starting this lesson I had previously created an ASP.NET website project named Lab18_csharpuniversity_webserviceclient.  That project contained a web reference to the old version of the getCustomers() method.  Remember that the old version of the method did NOT contain any input arguments so the ASP.NET client web application had the following code to call the web service:

CustomerWebService.CustomerData customerdata =
            new CustomerWebService.CustomerData();
        string dataXML = customerdata.getCustomers();

When I tried to run this code after the back-end web service was changed, I received the following error:
System.Web.Services.Protocols.SoapException: Server was unable to process request.
System.NullReferenceException: Object reference not set to an instance of an object
 at CustomerData.getCustomers(String pLastName)

Click here to watch a video that shows exactly what happened when I ran the client project and the SoapException error coming up.

Next, in the Lab18_csharpuniversity_webserviceclient project I decided to change the web form GridView_SQLServer.aspx and add a TextBox so that the user can type in an optional last name as search criteria.  I updated the click event code for the Show Customers button as follows:

CustomerWebService.CustomerData customerdata =
            new CustomerWebService.CustomerData();
        string dataXML = customerdata.getCustomers(txtLastName.Text);

Notice that I am passing the value from the txtLastName text box as an argument to the getCustomers web service method.  When I tried to run this code, I received the following error from the compiler:
No overload for method ‘getCustomers’ takes ‘1′ arguments

Now that error message wouldn’t even let me compile the application.  Click here to watch a video that shows how I added the new TextBox and tried to call the new version of the web service method.  The reason that the compiler was throwing the error message is because whenever you Add a Web Reference to your ASP.NET application in Visual Web Developer or Visual Studio, the IDE actually hits the web service, obtains a definition for all of the web service methods, and stores this definition in some files inside your project.  You should see a folder that gets created in your project called App_WebReferences.  In that folder, there are some IDE generated files that contain the web service definition.

Since the web service changed in the back-end project Lab18_csharpuniversity_webservice, I would then have to update the definition of that service in the client project files of Lab18_csharpuniversity_webserviceclient.  The proper way to do this is by right clicking on the App_WebReferences folder in your client ASP.NET project and choosing the option to “Update Web/Service References”.  This will cause the IDE to go and grab the latest version of the back-end web service definition file.  Click here to see a video that shows how I refreshed my client ASP.NET application with the most up to date web service definition and tested my new search web form

When you right click on the App_WebReferences folder and update the web references, you are essentially updating the definition for all of the web services that your ASP.NET application is using.  This means that if you had references to several different web services, it will go to each and every one of them to get an updated set of definitions.  This may not be necessary in some situations where you just want to update ONE web service definition (i.e. the one that you know has changed).

If you only want to update a particular web service definition, you can expand the App_WebReferences folder and right click on the individual service class you need to refresh, then choose “Update Web Reference”.  Click here to watch a video that shows how I updated an individual web service class reference for my CustomerData web service class.

So what kind of web services are you calling in your ASP.NET application?

Category: Advanced ASP.NET

Click here to download the source code for this lesson

In the previous lesson we explored how to create and ASP.NET C# web service that executes a database query and returns a list of data.  The data was returned as a string of XML.  In THIS lesson I am going to show you how to call a web service from an ASP.NET web application and display the return data in a GridView server control.  If you haven’t already done so, I recommend that you click here and read the previous lesson since this lesson basically builds on top of it and we will be calling the web service created in that lesson.

As it turns out, web services are very common these days for many reasons.  They provide a good way for different applications, languages and frameworks to interoperate with each other.  For example, a Java application can easily call a .NET application and a .NET application can easily call a Java application.  This is very powerful and it is implemented in many of the organizations that I have worked or consulted for, including government environments.

Before I get started with the lesson I want to do a quick recap of what the web service that we will be calling actually does.  In the previous lesson, I created a web service named CustomerData.  The CustomerData web service has a method named getCustomers().  The getCustomers method queries a database table named “customer” and then places the results of the query in an ADO.NET DataSet object.  I then take the data in DataSet object and transform it into an XML string that is returned to the caller of the web service method.  The DataSet object has a method named GetXml() that allows me to do this.  The XML is basically a list of customers that are in the database table.

Alright now lets talk about what has to happen on the client side.  On the client side, we are going to create an ASP.NET web application that will call the web service and display the customer data on a web form in a GridView.  In order to be able to call a web service from an ASP.NET web application, you have to Add a Web Reference to your web site project.  When you do this, Visual Web Developer creates some web service project files for you automatically.  These web service files are responsible for actually calling the web service and they are beneficial to you as the developer because they make it easy for you to integrate the web service into your ASP.NET application just like you are referencing any other class library or .NET class. 

You don’t need to be concerned about what is in those project files, you just have to know how to use them and that is what I’m going to cover in this lesson.  *Even though we are going to call a .NET web service in this lesson, the process to call a Java web service is pretty much identical.  That is why web services are so powerful and ASP.NET abstracts out all of the details behind the scenes from you as the developer so that you can concentrate on your application business logic.

Now let me walk you through how I called the web service from my ASP.NET web application and you can follow along.  I created a new web site named Lab17_csharpuniversity_webserviceclient.  Then I deleted the Default.aspx web form from the project.  Next I added another existing web form that I had previously created to the web site.  That web form is named GridView_SQLServer.aspx and I decided to re-use it for this lesson.  It basically contains a GridView that looks like this:

<asp:GridView ID="gvCustomers" runat="server"

AutoGenerateColumns="False">
            <Columns>
                <asp:BoundField DataField="first_name"

HeaderText="First Name" />
                <asp:BoundField DataField="last_name"

HeaderText="Last Name" />
            </Columns>
</asp:GridView>

Notice that it has two BoundField columns that map to my database table “customer”, which has the customer’s first and last name.  The form GridView_SQLServer.aspx also has a Button that will fetch the data for the GridView when it is clicked.  I am going to place the code that calls the web service in the event handler for that Button.

Next, I right clicked on the project name in the Solution Explorer and chose “Add Web Reference”.  The Add Web Reference window appeared.  In this window you have to put the URL for the web service that you want to call.  So how do we find that URL?  Here is how.  I opened up my other web service project Lab17_csharpuniversity_webservice in a separate instance of Visual Web Developer.  So I had two Visual Web Developers running simultaneously.  Then I clicked the play button in my web service project and it brought up the Internet browser with the web service page CustomerData.asmx.  I then copied the entire full URL from the top of the browser.  The full URL to my web service is:
http://localhost:1775/Lab17_csharpuniversity_webservice/CustomerData.asmx

Then I left the web service running (it is important to leave it running) and I went back to my web application project and pasted the URL into the Add Web Reference window.  Next I clicked the Go button and waited for a few seconds.  Visual Web Developer will automatically go and read your web service’s description file.  It will display a list of the methods available and it lists them as operations.

Following that I changed the Web reference name to “CustomerWebService”.and clicked Add Reference.  At that point Visual Web Developer will add some files to your web site project.  Now let’s go and put some code to actually call the web service.  I created a click event handler method for the Button on my web form GridView_SQLServer.  If you are looking at the source code for this example, take a look at the method btnCustomers_Click:

 //Call the web service to get the customer data
        CustomerWebService.CustomerData customerdata =
            new CustomerWebService.CustomerData();
        string dataXML = customerdata.getCustomers();

        //Convert the XML data into a DataSet object
        StringReader datasetReader = new StringReader(dataXML);
        DataSet displayDS = new DataSet();
        displayDS.ReadXml(datasetReader);

        //I assign the results of the query to the GridView control
        gvCustomers.DataSource = displayDS;
        //DataBind causes the data to display on the web form
        gvCustomers.DataBind();

In order to call a web service in your code, all you have to do is type “CustomerWebService” and then a period “.” and the intellisense window will come up.  I then chose the name of my web service class which is “CustomerData”.  Instantiated an instance of the CustomerData class and stored a reference to it in the variable “customerdata”.  You see that this is identical to how you normally would instantiate a regular C# class.

On the next line is where I actually called the web service method getCustomers() and saved the result in a variable named “dataXML”.  Then I used a StringReader object in order to pass the XML data to a DataSet method named ReadXml.  ReadXml will take an XML string and basically translate the data into a DataSet object.  This is necessary so that we can easily bind the data to the GridView, which happens on the line “gvCustomers.DataSource = displayDS;”.  Let me summarize the steps involved here so you can recap in your mind.

  1. I added a web reference to my web service.
  2. I instantiated an instance of the web service class CustomerData.
  3. I added a web reference to my web service.
  4. I passed the StringReader object to the DataSet ReadXml method.  The DataSet will then read the data and load it into its internal object structure.
  5. I bound the DataSet object to the GridView gvCustomers just like I would normally do using the GridView DataSource property.

When I run the web application and click on the Show Customers button, it will make a call to my web service and display the results of the operation in a GridView list.  You can repeat this process with any other web services that you want to use in your ASP.NET web application.

*An important thing to note here is that I left my web service project running when I went to add my web reference and unit test my web application.  If you don’t do that, you will see an error message that looks like “Unable to connect to the remote server”.  This is because if you are developing with Visual Web Developer or Visual Studio, the web service isn’t really deployed anywhere yet.  If you deploy the web service into IIS either on the same machine or another machine, you would be able to reference that without running Visual Web Developer or Visual Studio, but when you are initially developing the web application client, you can do exactly as I did in this lesson.

*Another thing to pay attention to is that the port number that the web service will run on can change each time you close and open Visual Web Developer or Visual Studio.  In my example the port number was “localhost:1775″, but if I close Visual Web Developer and open it again later to run the web service, there is no guarantee that port 1775 will be used again.  In fact, when I recorded the video for this lesson you will see that a different port was used versus what I put in the text of this lesson.  If the port number for your web service changes, you can simply open the web.config file in the web site project and change it.  Look for a configuration in the appSettings part of the web.config that you can change.

Stay tuned for the next lesson where I will cover how you can update your web service client project files anytime the back-end web service changes.

Click here to watch a video where I show you how to perform all the steps involved with adding the reference to the web service and calling it in your web application source code.

So what do you intend to call web services for in your application?

Category: Advanced ASP.NET

Click here to download the source code for this lesson.

In this lesson I am going to discuss how to create an ASP.NET C# web service that runs a database query and returns a list of data.  The web service created in this lesson, queries data from a database table named “customer”.  In the next lesson, I will discuss how to call or consume the web service created in this exercise and display the customer data on a web form using a GridView server control, so please read that lesson when you finish with this one.  I split these two apart in order to make it easier to follow along since there are several steps involved.

Before I begin with the lesson, let me just cover some background information about web services and what they are used for.  A web service is a special kind of web site.  It is different from a traditional ASP.NET web site that produces HTML code.  In fact, a web service had no graphical user interface and produces XML.  A web service exposes one or more methods that your application can call remotely.  This is called a remote procedure call.  It basically means that you can have web service A sitting on a web server and another ASP.NET web application B sitting on a different server, and application B can call or communicate with web service A, even though they are in separate physical machines.  It turns out that this feature of web services makes them very useful for many reasons: scalability, ensapsulation of logic, and security.

Web services are implemented internally using an Internet protocol called SOAP, which passes XML messages back and forth between a web service client application and a web service.  The SOAP protocol is an Internet standard which makes web services interoperable or cross-platform (e.g. Java can communicate with .NET and .NET can communicate with Java); the two can integrate with each other seamlessly by using web services.  You don’t have to understand how SOAP works in order to program an ASP.NET web service, and a lot of programmers probably don’t.  That is one of the strengths of the .NET framework and the Visual Studio IDE.  In this lesson you will learn how quickly you can create web services and become productive with them.

Alright, let’s get started.  To create an ASP.NET web service with Visual Web Developer, click on File->New Web Site, then choose ASP.NET Web Service from the templates list.  Type in the name of your web service project at the bottom of the screen and click OK.  In this lesson, I called my project Lab17_csharpuniversity_webservice.  The IDE will create a template project with one default web service called Service.asmx.  Notice the file extension of .asmx, which is different from what we are used to seeing with traditional ASP.NET web form (.aspx).

The name Service.asmx is too generic, so it’s a good idea to create one that has a more meaningful name for your application.  Right click on the project name in the Solution Explorer and choose Add New Item.  Choose Web Service from the templates list and type in the name for the new service at the bottom.  I named my new service file CustomerData.asmx.  Make sure that Place code in separate file is checked.  Click OK and the IDE will create the new file.  You will notice that the IDE automatically generated a file named CustomerData.cs in the App_Code folder.  That is the code-behind file and contains all the programming for the web service.  If you open the file CustomerData.asmx you will see that it’s just a one liner that references the CustomerData.cs file, where the code actually is.  Right click on the CustomerData.asmx file and choose Set as start page.  Then delete the files Service.asmx and Service.cs since we won’t need those anymore.

What we are left with after all of this are the files CustomerData.asmx and CustomerData.cs.  Now it’s time to add some code into our web service.  Open the file CustomerData.cs and add the following two lines of code at the top:

using System.Data;
using System.Data.SqlClient;

Next, we are going to replace the existing method named HelloWorld (sorry hello world lovers).  Highlight the HelloWorld method and replace it with the following code:

[WebMethod]
    public string getCustomers()
    {
        SqlDataAdapter dbadapter = null;
        DataSet returnDS = new DataSet();

        using (SqlConnection dbconn = new SqlConnection(
            "Server=localhost;"
            + "Database=csharpuniversity;"
            + "User ID=sa;"
            + "Password=Sqlserverpass$123;"
            + "Trusted_Connection=False;"))
        {
            SqlCommand cmd = new SqlCommand();
            string sqlQuery = "select * from customer";

            cmd.CommandText = sqlQuery;
            cmd.Connection = dbconn;
            dbadapter = new SqlDataAdapter(cmd);

            dbadapter.Fill(returnDS);
        }

        return returnDS.GetXml();
    }

Let’s talk about this method.  First you will notice that I had to put [WebMethod] right above the method declaration.  This lets the ASP.NET IDE know that you intend to expose this method so that it can be called by application clients of this web service.  If you forget to put that, your method won’t be accessible to applications calling this web service CustomerData.asmx.

Next, the method itself is pretty basic.  It executes a query against a SQL Server database and returns all of the data in the source table “customer”.  A trick that I am using here is to return the database data as an XML string.  The ADO.NET DataSet class has a method named GetXml that makes this quite easy.  The benefits of having my web service method getCustomers return back an XML list of data are that it is: easy because it doesn’t require much coding (i.e. I don’t have to transform the data into any typed object) and that it makes the web service interoperable with Java and other non-.net languages that can interpret XML.  This technique of returning XML data from a web service method can be used in any scenario where you need to return a list of data to client applications.

As a final part of this lesson, we need to unit test the web service and make sure that it works correctly.  Make sure that your database is up and running before you proceed.  To test an ASP.NET web service, all you have to do is click the Play button just like you would with a traditional ASP.NET web site project.  Turn on debugging if you get prompted.  Visual Web Developer will launch your web browser with a URL that looks similar to: http://localhost:1775/Lab17_csharpuniversity_webservice/CustomerData.asmx.

Notice that the .asmx file is the one that represents your web service.  A web page will come up that lists all of the methods in your web service class that were marked with the [WebMethod] directive.  In my example it is the method getCustomers.  If you click on getCustomers, it will take you to another web page where you can actually test the method.  The web page that comes up will have a bunch of information about the SOAP request and response.  You don’t need to be concerned about all of that.  You can click on the Invoke button, and that will execute your method.  Then another web page will open with the results of the operation.  If any data was returned, it will be displayed in XML format.  In my case I get a list of XML nodes that look like:

<Table>
<customer_id>3</customer_id>
<first_name>Mike</first_name>
<last_name>Richardson</last_name>
<email_address>[email protected]</email_address>
</Table>

Each node represents a unique customer in my database.  This XML string is what will be received by client applications that call this web service.  Notice that the .NET framework and IIS automatically create this set of test web pages that we just used in order to allow developers to test their web services from a web browser.  This is very helpful and can even help in production debugging where I have personally used this feature to diagnose web service problems.  By default IIS, only allows access to this unit test application if you are running it from the same machine where the web service is deployed.

One more thing I want to cover before closing out this lesson, is to discuss the XML Namespace of the web service.  Every web service has an XML Namespace name that is used by the internal SOAP processors to uniquely identify the service.  Think of the XML Namespace as like the identity fingerprint for the service.  It ensures that your web service contains a unique branding that logically differentiates it from other web services.  You can set the Namespace for your web service at the top of the code-behind file.  You can use a common Namespace for your organization as I did in my file:

 

[WebService(Namespace = "/webservices")]

Click here to watch a video where I show you how to perform all of the steps mentioned above to create an ASP.NET C# web service.

What do you intend to use a web service for?

Click here to download the source code for this lesson.

In this lesson I am going to show you how to use the ASP.NET FileUpload and CustomValidator controls.  We will walk through an example together.  I setup a web form named FileUploadPage.aspx that allows a user to upload a .jpg picture file to the server.  The example code that I have performs some basic validation on the uploaded file such as ensuring that the size of the file falls within a certain range.  If the validation succeeds, the code saves the file to a folder called “uploads”.  Let me first describe the two server controls a little bit.

The ASP.NET FileUpload control can be used when you want the user to upload a file and then save the file on the server or in a database.  You have be careful when you use this server control because you are giving the user the ability to temporarily perform operations on the web server which could be hazardous to your server’s health.  An example of this is if a malicious user repeatedly submits large files to clog your server’s resources (hard drive space, etc.).  *A couple of tips to keep your applications more secure are to restrict the size of the files that you allow the user to upload and do NOT allow the user to name the target file that is saved on your web server (i.e. your application should create the filename).  I will show you how to implement these two tips in this lesson.  When you use the FileUpload control you have the option to either save the uploaded file to the server’s hard disk, or you can access the file in memory and put it somewhere else (e.g. in a database table).  *Putting large files in a database table is something that I would avoid because it can turn your database into a huge and difficult to manage entity.

The ASP.NET CustomValidator control allows you to create server side validation methods and associate them with particular controls that are in your web form.  This is contrast to the RequiredFieldValidator, RangeValidator and RegularExpressionValidator controls that I covered in previous blog entries.  With those other validation controls, you don’t really have to write any code, but with the CustomValidator you can create your own validation rules in C# code.  In this lesson I am going to use the CustomValidator to make sure that an uploaded file size doesn’t exceed a predefined maximum size.  The CustomValidator control does have a couple of Properties that are similar to the other validation controls.  Those are the ControlToValidate and the ErrorMessage properties.  Click here to learn more about the other validation controls and properties mentioned here.  Look for the articles with the title of ASP.NET validation controls.

Alright, now let me take you step by step through the lesson.  First I dragged a FileUpload control onto my web form FileUploadPage.aspx.  The FileUpload control is in the Standard group of Toolbox controls.  After you drag it onto a web form the FileUpload looks like a TextBox with a Browse button right next to it.  The FileUpload server control is actually rendered as an HTML input type=”file” tag in the browser.  The ID of my control is “FileUpload1″.

<asp:FileUpload ID="FileUpload1" runat="server" /> 

Next I added an Upload button that is responsible for posting the web form back to the web server.  Then I dragged a couple of CustomValidator controls underneath the button.  The CustomValidator controls are in the Validation group in the Toolbox.  The first CustomValidator control that I put in my form is responsible for making sure that the uploaded file is at least 1K in size.  I set its ErrorMessage property to “File must be at least 1K”.  If the validation fails for this control, that message will be displayed to the user on the web page.  Next I set the CustomValidator OnServerValidate property to “validateMinimumFileSize”.  The OnServerValidate specifies the name of a server side method that will execute the code for the CustomValidator control.  In my example, I have a method in my code behind class file named validateMinimumFileSize.  When my web form executes and a post back occurs, ASP.NET will automatically call my validateMinimumFileSize method.  This only happens during post backs (e.g. when a button is pressed).

<asp:CustomValidator ID="CustomValidator1" runat="server"
 ControlToValidate="FileUpload1"

ErrorMessage="File must be at least 1K"
 OnServerValidate="validateMinimumFileSize"></asp:CustomValidator>

I then created the validateMinimumFileSize method in my FileUploadPage code behind class file.  Since the method is going to be called automatically by the control and ASP.NET, the method has to follow a specific signature (i.e. you have to put a couple of standard method input arguments).  I will tell you a little bit more about the arguments later.  Let’s take a look at what my example method looks like.

protected void validateMinimumFileSize(object source, ServerValidateEventArgs args)
{
 //Get the information about the file that was uploaded.
 HttpPostedFile postedfile = FileUpload1.PostedFile;
 
 //If the file was less than the minimum size
 //of 1K, reject it.
 if (postedfile.ContentLength < 1024)
 {
      args.IsValid = false;
      mPassedValidation = false;
 }
 else
      args.IsValid = true;
}

On the first line of my method, I am getting an HttpPostedFile object from the FileUpload control.  That object contains the file that was uploaded to the server and has a ContentLength property that I can access to determine the size of the file.  I check that value and if it is less than 1K, I set the IsValid property to false.  The args input argument contains the IsValid property so that your method can communicate with ASP.NET to let it know whether or not the validation failed.  If you set it equal to false, ASP.NET will assume that the validation failed and display the ErrorMessage on the web page.  Setting it to true, passes the validation.

I repeated pretty much the same steps for the second CustomValidator control that checks to make sure that the file size doesn’t exceed a certain limit.  In that case I am calling a method named validateMaximumFileSize.  That method looks very similar to the other validation method above.  If I wanted to perform additional validation logic in this web page, I could drag additional CustomValidator controls and create more server side methods to perform validation business logic.

The advantage of using CustomValidator in this fashion is that it separates the validation logic from your other processing.  Also, it comes in handy because you can create as many server side rules as you want and ASP.NET will automatically call all of them for you.  This is a big benefit of event driven programming in C# with ASP.NET.  Now let’s look at the actual processing of the file during the upload.

I created a button click event handler method for the Upload button named btnUpload_Click.  Here it is.

protected void btnUpload_Click(object sender, EventArgs e)
{
//If the file passed all the validation rules, only
//then do we save it to the hard drive.
if (mPassedValidation)
{
string serverfilename = System.Guid.NewGuid().ToString()
+ ".jpg";
FileUpload1.SaveAs(Server.MapPath("") +
"\\Uploads\\" + serverfilename);
txtResults.Text = "File successfully uploaded at "
+ DateTime.Now.ToString() + "\r\n";
}
else
txtResults.Text = "";
}

In this method I am creating a unique file name for the uploaded file by using a .NET Guid object.  This will create a file name that will look something like “020261de-0627-43a2-b4f4-a0911488e7f5.jpg”.  This is to ensure that no two users can have the same file name and it also eliminates the security risk of allowing the user to name their file on the server.  To save the file to the hard disk on the web server I am calling the SaveAs method of the FileUpload object.  That method expects the full path file name of where you want to save on the hard drive.  I save the uploaded images into an Uploads folder.

One thing you will notice is that I use a shared class instance variable named mPassedValidation in order for all of the methods to be able to communicate with each other.  If any of the validation methods fail, they set that boolean variable to false, which prevents the saving of the uploaded file onto disk.  To read more about class instance variables click here.

To summarize, there is a couple of things going on inside this web page.  I have a control that is responsible for uploading a file to the web server.  That control checks to ensure that all validation passed before it saves the file.  Finally there are a couple of separate validation controls that actually perform the logic of ensuring that the file size is within a given desired range.

To watch a video of this example project actually running click here.  See how I choose different files with different sizes and see how the program behaves.

So how do you intend to use the FileUpload or CustomValidator controls?