Developer Feature Article |
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'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.
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.
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.
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.
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.
|
 |
 |
|
Last Updated: Friday, January 4, 2002 |
|
|
 |
 |
|