microsoft press home   All Products  |   Support  |   Search  |   microsoft.com Home  
 
  Microsoft Press Home  |   Register Books  |   Site Index  |   All Books  |

 

Advanced Search
Books about:
Books for:
Products for:



Developer Feature Article
Developing Robust Applications Quickly with Microsoft Visual Studio .NET
Developing Robust Applications Quickly with Microsoft Visual Studio .NET

By Scott Mauvais

In last month's article, "Microsoft ASP.NET: A Better Way to Build Dynamic, Secure Web Applications ," I discussed the productivity enhancements in the Microsoft® .NET Framework. For me, productivity is the most important yardstick in a development environment. If I have to struggle to build code, or if I have to spend the majority of my time writing tedious helper classes rather than focusing on the real value of my solution, I don't really care about how elegant the object model is or how many platforms it supports.

In that article, I demonstrated how productive the .NET Framework really is by showing you how to build a simple console application in C#T and then port it to a Web Service. (Porting may be a bit generous; I simply cut and pasted my class and then added four lines of code!) With this Web Service in hand, I walked you through all features that the Microsoft .NET Framework automatically builds for you such as the test harness and Web Service Description Language (WSDL) code.

This month, I am going to take a similar approach and show you how to use Microsoft Visual Studio® .NET to build applications quickly and easily. To that end, I created a simple application that you can download. Whether your primary development environment is a laptop you carry from client-to-client or a dual processor workstation that is always connected to the enterprise resources, Microsoft Visual Studio .NET has a set of tools to help you with everything-from writing code on your machine to seamlessly migrating it to a production environment. And Microsoft Press® has an impressive library of resources to get you up to speed.
  
    

Getting a Head Start

Initially, when I was thinking about this article, I had a hard time deciding what new features of Visual Studio .NET I would cover because there are so many important ones. In the end, I chose to focus on the ones that have added the most value to my projects with the least effort on my part.

Accordingly, I will not cover some important features such as support for teams of multiple developers, the separation of presentation logic and HTML afforded by the ASP.NET code-behind support and ADO.NET. Although these are all very important from an architectural and maintenance standpoint, they did not immediately improve my productivity. To learn more about the code-behind mode, see Designing Microsoft ASP.NET Applications by Douglas J. Reilly; for ADO.NET, see Microsoft ADO.NET Step by Step by Rebecca M. Riordan.

Probably the single most important step I have taken toward improving my productivity with Microsoft Visual Studio .NET was reading as much about the .NET Framework and associated languages as I could. This helped me focus on making the best use of the usability improvements in Visual Studio .NET without having the newness of the platform and language semantics get in the way. If you are working to come up to speed on Microsoft's new languages, two good books are Charles Petzold's Programming Microsoft Windows with C# and Upgrading Microsoft Visual Basic 6.0 to Microsoft Visual Basic .NET by Ed Robinson, Michael Bond, and Robert Ian Oliver.

As for Microsoft Visual Studio .NET itself, the features I cover fall into three broad categories: user interface enhancements, debugging and instrumentation support, and-for lack of a better term-features I have used to wow clients.

 

Cranking Up the Dynamic Help Engine

OK, I admit it: I am not particularly good at reading readme files and the associated release notes. I have always felt a good test of a product was whether I could figure out how to use it without reading the documentation. As a result, one of the very first features I find myself getting acquainted with is the online help.

By far the most useful Visual Studio .NET feature to me is the Dynamic Help system. If you haven't used it yet, you can think of it as a completely nonintrusive version of Office Assistant that actually provides value. To use it, simply highlight the element about which you want more information and then hover over the Dynamic Help icon-the Dynamic Help pane, shown in Figure 1, pops out with the most relevant topics available.

Figure 1: Microsoft Visual Studio .NET

Figure 1: Microsoft Visual Studio .NET's Dynamic Help gives you the exact topic you want just when you need it.

When the Dynamic Help engine selects the topics, it not only looks at the object (Page in this case) you selected but at the context in which you used it (for example, @ Page rather than Page.Response() ). As a result, you get much better results than if you had simply performed a keyword search. For example, I seem to have a mental block when it comes to the ASP page directives. For some reason, I can't seem to remember the syntax for all of them. As you can see from Figure 1, when I highlight the word Page at the top of my Web Form, the Help system provides me with a link to "Directives for Web Forms Pages". Conversely, if I had typed "page directives" into the standard Help index, I would have been sent to a page listing the new directives for ASP.NET, which is not what I wanted.

Better yet, Dynamic Help works not only with text in the code window but it also provides guidance with all the aspects of Visual Studio .NET-from programming against the controls to tweaking configuration settings to working with the add-on tools. For example, when you are navigating through your enterprise with Server Explorer, Dynamic Help provides links to topics that help solve credential and privilege problems when accessing remote servers as well as configure the various components exposed in Server Explorer. In addition, Dynamic Help provides links to technology backgrounders on Active Directory® and Microsoft Message Queue.

  

Thinking Outside the Box

Speaking of Server Explorer, this is another one of my favorite features of Visual Studio .NET. Server Explorer enables me to access all the services I need from inside the Visual Studio .NET user interface. Previously, I had to keep four or five applications and a couple Terminal Server sessions open to manage the resources my application used. In addition to taking up valuable screen real estate (not to mention memory-none of these apps are what you would call svelte), each application had a different user interface that I had to remember-now, was that Tools -> All Tasks -> New? Or was it File -> New? Or do I need to right click and select Add from the context menu? The only problem with Server Explorer is that it makes justifying that second monitor a bit more difficult.

This tool becomes even more important in developing distributed applications when many of the resources you need are not local to your box. In these cases, before you can manipulate the resources, you need to find out what is available. This becomes essential in fast-paced team environments or when you have one group of developers building one set of components that another group will call in their code.

Take a typical example of a database project where I'm working on the middle tier logic and the DBAs are writing the stored procedures. In this example, I need to call a stored procedure but I do not remember all the arguments and their data types. Sure I could go read the spec (assuming there is one and that it is even remotely up to date), or I could fire up isql and run sp_helptext and weed through the output. By using Server Explorer, as shown in Figure 2, I can point and click my way through the hierarchy and inspect the stored procedure of interest. I can even execute it and take a look at the data to make sure it is really the one I want.

Figure 2: Server Explorer lets you examine resources on any server without ever having to leave Microsoft Visual Studio .NET.

Figure 2: Server Explorer lets you examine resources on any server without ever having to leave Microsoft Visual Studio .NET.

Assuming I've found the procedure I want, I can simply drag the stored procedure from Server Explorer and drop it on my form, and Visual Studio .NET will take care of all the configuration for me-from the connection string to the command type all the way to defining the input and output parameters. All I need to do is set the parameter values and call the procedure.

 

Drag-and-Drop Web Services

While we are on the subject of drag-and-drop, let's take a look at how you can integrate Web Services into your application. If you have ever hand-coded a SOAP request, you will love this.

As a starting point, I use the Web Service I created in last month's article. You may recall that I created a service called NewMath which exposed a Calc.Add() method that returned the sum of the two numbers passed in. Certainly not rocket science but useful for demonstrating the technique.

To add this Web Service to your project, go to Solution Explorer, right-click on References, and select Add Web Reference. This brings up the Add Web Reference Wizard where you tell Microsoft Visual Studio .NET where to look for the Web Service. You can connect to a UDDI directory, search for Web References on your local Web server, or directly enter a URL. I chose local server and then selected the NewMath Web Service (http://localhost/NewMath/NewMath.vsdisco) from the next screen. This takes me to final screen of the wizard, shown in Figure 3, where I can either directly add the reference or make sure I have the correct one by inspecting the contract or reading the documentation. Since I wrote it, I know it is the one I want, so I just clicked on Add Reference.

Figure 3: The Add Web Reference Wizard walks you through adding a Web Service to your project.

Figure 3: The Add Web Reference Wizard walks you through adding a Web Service to your project.

If you are new to consuming Web Services in Visual Studio .NET and are unsure of how to reference the class or syntax for calling the method, you can drag-and-drop your way there. First go to Class View, and navigate to the class and drag it on to your code window. With a little help from IntelliSense®, you can easily figure out the syntax. To demonstrate this feature, I created the simple Web application (you can download the source code from my Web site) in Figure 4 that calls various implementations of the NewMath.Calc class. Listing 1 shows the relevant code. 

Figure 4: My sample application shows you how to call a Web Service and C# .NET, Visual Basic .NET, and COM components from a simple ASP .NET Web page.

Figure 4: My sample application shows you how to call a Web Service and C# .NET, Visual Basic .NET, and COM components from a simple ASP.NET Web page.

Listing 1: A simple Web application
Long                lSum = 0 ;
VS.localhost.Calc   oWS  = new VS.localhost.Calc() ;

lSum = oWS.Add (Convert.ToInt32(this.txtX.Text)
               ,Convert.ToInt32(this.txtY.Text)) ;
 
this.txtOutput.Text = "WS says: " + lSum.ToString();


Pretty simple, isn't it? Everything should be clear with the possible exception of the VS in VS.localhost.Calc. That is just the name of my project; I guess I wasn't feeling very creative when I was writing the sample code.

As you can see, to keep it short and uncomplicated, I have not included any error handling or input validation, which are essential for any code, no matter how trivial. Once again, this is sample code, not template code.

 

Using the Trace Object to Debug Pages

Of course, I write perfect code that works the very first time-simply compile and I'm done. I rarely have syntax errors, so I usually leave that grunt work of building to junior developers, too. I'm sure you're the same, so you may be tempted to skip the next section. However, you may want to skim over it just in case you ever need to help a "friend" debug their code.

Suppose this friend has built this Web application and users are complaining about random errors and bad data on a key page. Fortunately, you (uh, your friend) can reproduce the error in a test environment, but it is intermittent at best. Unfortunately, it is a very complex, data-dependent page with a lot of branching logic and looping constructs. Normally, to track down a problem such as this one would result in the code shown in Listing 2.

Listing 2: Tracking down errors

Response.Write "Starting " & CStr(Now)
' do something
Response.Write "Got here."
' If PhaseOfMoon="Blue" then.
Response.Write "Not dead yet."
' big long loop
Response.Write "XBOX!!!!"
Response.End


You would then start running the application against various datasets until you track down the location of the problem. Once you have found the location, you would use Response.Write() to write out all the relevant variables and errors to see if you could figure anything out.

This approach has two big problems. First, it requires modifying your code, and when you are debugging something, the fewer changes the better. I can't tell you how often I've heard my friend say he solved a problem only to find it resurface after moving all the Response.Write debugging code. It's so much fun modifying the code-let's do it again!

The second drawback is that this approach only works when you are solving a linear problem. In other words, all is fine as soon as you get to the XBOX line.

Visual Studio .NET solves both of these problems by allowing you to instrument your application with trace flags. To use them, you add either Trace.Write or Trace.Warn at the same places you would normally include a Response.Write.

The main difference between the Trace and Response objects is that the output of the Trace object is off by default. Also, just by turning on the trace flag you will get a great deal of diagnostic information without writing any instrumenting code of your own, as you can see in Figure 5. I have scrolled down a bit so that you can see more of the trace output; just off the top of the page is the standard output of my Web application.

Figure 5: The Trace object allows you to add custom events to the trace output.

Figure 5: The Trace object allows you to add custom events to the trace output.

Everything in the screen grab is automatically produced with the exception of the two lines in red, which I added using the following code:

Trace.Warn("WS", "Starting") ;
// Same code as Listing 1.
Trace.Warn("WS", "Ending value:  " + lSum.ToString() ) ;

Trace.Warn is an overloaded method, but the way I called it here, it takes two arguments: the first is a custom-defined category and the second is the actually traced message. I used the "WS" category because this message originated with the Web Service implementation of my NewMath.Calc class. Also, I chose to use the Trace.Warn method rather than Trace.Write. The only difference is the output of .Warn is red, and I find it easier to locate the messages I'm interested in if they are red.

You can turn Tracing on for a single page with the <%@ Page trace="true"%> directive or globally for the application by modifying the Web.config file. The functionality of these two approaches is somewhat different, so you will want to read up on them in the online help.

In a nutshell, the page level approach has the benefit of showing you the trace output along with the page. The downside is that every user gets to see the output, so it is not appropriate for anything other than unit testing in development. Conversely, by changing the Web.config file you are able to specify that output only be available to users connecting via http:/localhost/, so you could potentially use this on production systems. The downside is because the Web.config approach is global, all pages are affected, so you may see a performance hit. Another benefit of using the Web.config file is that is supports another option: pageOutput=false. This enables you to redirect all the trace output away from the page and send it to the listener. You can attach to the default listener by appending Trace.axd to the root URL for your app. In this example, it would be: http://localhost/VS/Trace.axd

   

Time to Impress the Clients

Finally, I want to quickly point you to two features that have really impressed potential customers. I won't go into much detail because they are pretty obvious and well documented.

The first is a way that you can configure your application so that it does not require cookies yet you are still able to maintain session state. Normally, you would uniquely identify a user by setting a cookie to some unique value (typically a GUID) and then using the cookie's value to correlate that user's visits across various pages and allow you to retrieve his or her session data from a database. With the recent (legitimate) concerns over Internet privacy and the (misplaced) assumption that cookies are the source of the problem, many companies have become somewhat concerned that they may face public (or worse, governmental) pressure to remove these evil cookies in the future.

ASP.NET enables you maintain session state without cookies by setting cookieless="true" in the sessionState section of the web.config file. With this setting, ASP.NET automatically generates a unique ID and places it in the URL. When the request comes in, it will munge the query string, pull out this ID, and use it to correlate a request to a given user. As an example, for one user in my sample application, the new URL looks like this:

http://localhost/VS/(dsuvdarcqfuiiqqi0mlmnfu0)/WebForm1.aspx

Talk about a time saver! Think about how long it would take to make that change across all the pages even on a relatively small site. Sure you could do a bunch of it with include files, but this would require that proverbial "non-trivial" amount of development effort-not to mention what it would take to test it adequately.

The final piece I will leave you with is the final step to get done in many projects-documentation. While I have heard many developers say (and some of them even meant it), "Read the code-that is documentation enough." With Visual Studio .NET, that statement is nearly true. Visual Studio .NET allows you to build your documentation right into the code and then extract it out and publish it in a customer-ready, professional-looking format.

Visual Studio .NET has introduced a new comment format. You can add documentation to your code by writing some XML at the beginning of classes, methods, events, and so on. You then set this XML off from the rest of the code and your other comments by starting each line with three slashes (///) rather than the two for normal comments. To produce the documentation, go to Tools | Build Comment Web Pages. Visual Studio .NET includes a parser that reads through the code, applies an XSL/T to these sections and produces HTML output.

Visual Studio .NET includes documentation of the elements it understands (search on "Tags for Documentation Comments"), but you are free to add more or provide your own XSL/T to format the output differently.

My goal in this article was to provide you with an introduction to Visual Studio .NET and show you how you can use it to build applications quickly and easily maintain them. I did this by starting off with the user interface improvements such as Dynamic Help and the Server Explorer. Next I showed you how easy it was to integrate Web Services into your application. I then moved on and walked you through adding trace code to your pages. Finally I concluded with a look at cookieless session state and the support for inline documentation.

At the beginning of the article, I talked about how Visual Studio .NET has a set of tools to help you at each step as you build an application on your laptop to the point where you deploy it in the data center. In this article, I covered the build part of the life cycle. Next month I will dive into the deployment, take a look at assemblies, and examine some strategies for packaging and deploying your code whether your application targets a single box, a farm of servers in your data center, or hundreds of unmanaged desktops.

Microsoft Press Solutions

Now that you have an overview of Visual Studio .NET you probably want to dive in and start writing some code. The best way to quickly come up to speed on the new Microsoft .NET languages is to pick up a copy of Programming Microsoft Windows with C# and Upgrading Microsoft Visual Basic 6.0 to Microsoft Visual Basic .NET. These books walk you through everything from the language semantics to the best practices in application design and coding standards.

Microsoft Press provides in-depth documentation for these and all the other issues related to developing for the .NET Framework. For a complete list of .NET titles from Microsoft Press, see the Inside Information About Microsoft .NET page.

For a more broad overview of all the Microsoft .NET technologies, you should look at David S. Platt's Introducing Microsoft .NET. This book has some great information on COM Interop, Windows Forms, and .NET memory management.

Another good book is XML Step by Step by Michael Young. This title is a practical, hands-on learning guide that clearly explains the basics of XML and shows both nonprogrammers and Web developers alike how to create effective XML documents and display them on the Web.

One of my favorites is Jake Sturm's Developing XML Solutions, which examines XML-related technologies for data exchange and shows how XML fits in the Microsoft Windows® architecture.

For a complete list of all the developer titles, see the Developer Tools section.

For some great links and the latest information on Web Services, see the MSDN Web Services home page. A good troubleshooting resource is Keith Ballinger's article on Web Services Interoperability and SOAP.

For more information on Microsoft Visual Studio .NET, see the Visual Studio Next Generation Home Page.

Top of Page
 
Last Updated: Friday, January 4, 2002