Introduction

Team-Fly    

 
.NET and COM Interoperability Handbook, The
By Alan Gordon
Table of Contents
Chapter Five.  Using Visual Studio .NET

Introduction

If you have used Visual Studio 6 or any of its constituent products, such as VB, Visual C++, and Visual InterDev, you are going to love Visual Studio .NET. Visual Studio 6, like all previous versions of Visual Studio, consisted of a set of separate and independent development environments that were bundled together for marketing purposes. The development tools in Visual Studio 6 were very different from each other. VB, Visual InterDev and Visual C++ have completely different GUI designers, debuggers , and code editors. The default keyboard bindings are different across these tools as are the standard libraries that are available to you in each tool. Cross-language development and debugging was difficult in this environment. Visual Studio .NET has finally delivered on the promise that Microsoft has been making for years to have all of its development tools share a common development environment. Because all .NET programming languages share the base class library from the .NET Framework, you also get the additional benefit of having a common standard library for all the development tools in Visual Studio .NET. Visual Studio .NET is so simple and easy to use that, in most cases, it is much better to use it than the command-line tools in the .NET Framework SDK even for simple projects. The only time you will likely still need to use the command-line compiler is to build multifile assemblies (which Visual Studio .NET does not support). Because Visual Studio .NET is such a time saver, I will use it for most of the remaining examples in this book. Because of this, I wanted to end this introductory section of the book by introducing you to Visual Studio .NET. I build a simple spell-checker component and two clients that use the component. The following is a high-level summary of the steps I will follow in this chapter:

  1. Create a spell-checker component.

  2. Create a Windows Forms client.

  3. Create a Web Forms client.

Creating a Spell-Checker Component

To create the spell-checker component, I perform the following steps:

  1. Create a Visual C# class library project.

  2. Implement the SpellChecker class.

  3. Add a strong name to the project.

  4. Compile the assembly.

Creating a Visual C# Class Library Project

Start Visual Studio .NET and then execute the following steps:

  1. Select File New Project. The New Project dialog will appear as shown in Figure 5-1.

    Figure 5-1. The New Project dialog.

    graphics/05fig01.jpg

  2. Select Visual C# Projects under Project Types and then choose Class Library under Templates.

  3. Change the name of the project to WritersTools.

  4. Select the location where you would like to save the project.

  5. Click OK.

Visual Studio .NET will create a new project. The project will contain two files: Class1.cs and AssemblyInfo.cs . AssemblyInfo.cs contains the assembly-level attributes for the WritersTools assembly. The contents of AssemblyInfo.cs are as follows :

 using System.Reflection; using System.Runtime.CompilerServices; [assembly: AssemblyTitle("")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")] 

The Class1.cs contains an empty class declaration as follows:

 using System; namespace WritersTools {     /// <summary>     /// Summary description for Class1.     /// </summary>     public class Class1     {       public Class1()       {         //         // TODO: Add constructor logic here         //       }     } } 

Notice that Visual Studio .NET has added a using statement for the System namespace and has enclosed the generated class in a namespace that has the same name as the name that I gave the project WritersTools. The comments marked with three slashes (///) are XML code documentation comments. The C# compiler allows you to embed the documentation for your classes into your code using the special, three slash (///) syntax as shown previously. You can put any well- formed XML in your documentation comments, but Microsoft has defined an XML schema that contains XML tags for most things that you need. There are tags to specify summary information about a type and the fields, properties, methods, and events of the type. There are also tags for documenting the exceptions that a type may throw and the parameters and return values for methods . There are also tags for embedding example code in your documentation comments and for adding see also cross-references. Table 5-1 summarizes the tags in Microsoft's XML code documentation schema.

Table 5-1. Tags in the documentation comments XML schema

Tag Name

Description

Usage

remarks

Used to document overview information about a class or type.

<remarks>

description

</remarks>

summary

Used to document overview information about a member of a class or type. Visual Studio .NET uses the summary tag to document the class or type, although the .NET Framework SDK documentation recommends that you use the remarks tag for this.

<summary>

description

</summary>

param

Used to describe the parameters for a method.

<param name="name">

description

</param>

returns

Used to describe the return value for a method.

<returns>

description

</returns>

value

Used to describe properties in a type.

<value>

description

</value>

exception

Used to document the exceptions that a class may throw.

<exception cref="member">

description

</exception>

seealso

Used to create cross-references to other information in the documentation.

<seealso cref="member" />

example

Used to create examples of how to use types and methods. This tag is usually used with the code tag.

<example> description

<code>

source code for example.

</code>

</example>

code

Used to create multiline code examples in your documentation.

See above.

c

Used to indicate that text within a description (for a summary, remark, and so forth) contains code.

<summary>

description

<c> code </c>

description

</summary>

The C# compiler includes a parameter called /doc parameter that will extract the comments from your code and generate an XML document that contains your documentation. The following command line will generate an XML document that contains the documentation for the Class1 class:

 csc /doc:mydocs.xml Class1.cs 

If you are using Visual Studio .NET, you can specify a file name for the XML documentation on the project property pages. To do this, perform the following steps:

  1. Select View Property Pages. The Project property pages dialog will appear as shown in Figure 5-2.

    Figure 5-2. The Project property pages dialog.

    graphics/05fig02.jpg

  2. Select Build in the Configuration Properties folder.

  3. Enter a file name in the XML Documentation File field.

  4. Click OK.

Although you can use the XML documentation feature with the command-line tools in the .NET Framework SDK, Visual Studio .NET contains some very nice features that make it easy to use XML documentation. Visual Studio .NET does an excellent job of thinking ahead and filling in most XML tags for you; you simply have to type in the information describing your types and members . For instance, if you type in the prototype for a new method in a class (the name, parameter list, and return value of the method) and then place your cursor right above the method and type the triple slashes (///) for an XML documentation comment, Visual Studio .NET will create the summary, param, and returns tags for the method. For instance, if you add the following method to your class in the Visual Studio .NET editor:

 public float TestDocs(int arg1,string arg2) { //... implementation omitted } 

and then type the triple slashes above the method, Visual Studio .NET will add the following text to your file:

 /// <summary> /// /// </summary> /// <param name="arg1"></param> /// <param name="arg2"></param> /// <returns></returns> 

All you have to do is to fill in the summary and add a description for each parameter and the return value. The Intellisense feature of Visual Studio .NET is also fully integrated with XML documentation comments. Therefore, if you are on a line that starts with triple slashes and you type the less than symbol (<) to open an XML tag, Visual Studio .NET will present a list of the available XML documentation tags. When you select one, it will fill in the closing tag and place your cursor between the opening and closing tag. You truly have no excuse for not documenting your code properly now.

Implementing the SpellChecker Class

I'll now replace the Class1 class that Visual Studio .NET generated with the implementation of a SpellChecker class. Change the code in Class1.cs to look as follows:

 1.  using System; 2.  using System.Collections.Specialized; 3.  using System.IO; 4.  namespace WritersTools 5.  { 6.  /// <remarks> 7.  /// A class that performs "simple-minded" spellchecking 8.  /// </remarks> 9.  public class SpellChecker 10. { 11. /// <summary> 12. /// The dictionary for the spell checker 13. /// </summary> 14.   private StringCollection mDictionary; 15. /// <summary> 16. /// The path to the dictionary file 17. /// </summary> 18.   private string mDictionaryPath; 19. /// <summary> 20. /// This constructor reads the initial dictionary 21. /// from the default location, dictionary.txt 22. /// </summary> 23.   public SpellChecker() 24.   { 25.     mDictionary=new StringCollection(); 26.     mDictionaryPath="dictionary.txt"; 27.     StreamReader dictionaryReader= 28.     new StreamReader(mDictionaryPath, 29.       System.Text.Encoding.ASCII); 30.     ReadDictionary(dictionaryReader); 31.     dictionaryReader.Close(); 32.   } 33. /// <summary> 34. /// This constructor reads the initial dictionary 35. /// for the spellchecker from the specified path. 36. /// </summary> 37. /// <param name="dictionaryPath">The path from 38. /// where spell checker should read its 39. /// dictionary 40. /// </param> 41.   public SpellChecker(string dictionaryPath) 42.   { 43.     mDictionary=new StringCollection(); 44.     mDictionaryPath=dictionaryPath; 45.     StreamReader dictionaryReader= 46.     new StreamReader(mDictionaryPath, 47.       System.Text.Encoding.ASCII); 48.     ReadDictionary(dictionaryReader); 49.     dictionaryReader.Close(); 50.   } 51.   /// <summary> 52.   /// A private method that populates the 53.   /// dictionary from a stream reader that 54.   /// is passed in as a parameter. 55.   /// </summary> 56.   /// <param name="dictionaryReader"> 57.   /// The stream that contains the dictionary 58.   /// for the spellchecker 59.   /// </param> 60.   /// <returns></returns> 61.   private int ReadDictionary(62.     StreamReader dictionaryReader) 63.   { 64.     int numWordsRead=0; 65.     string aWord; 66.     aWord=dictionaryReader.ReadLine(); 67.     while (aWord != null) 68.     { 69.       mDictionary.Add(aWord); 70.     aWord=dictionaryReader.ReadLine(); 71.       numWordsRead++; 72.     } 73.     return numWordsRead; 74.   } 75. /// <summary> 76. /// Checks if a word resides in the spellcheckers 77. /// dictionary 78. /// </summary> 79. /// <param name="aWord"> 80. /// the word to be spellchecked 81. /// </param> 82. /// <returns> 83. /// true if the word resides in the dictionary 84. /// </returns> 85.   public Boolean CheckSpelling(String aWord) 86.   { 87.     Boolean bRetval=false; 88.     if (mDictionary.Contains(89.         aWord.ToLower())) 90.       bRetval=true; 91.     return bRetval; 92.   } 93. /// <summary> 94. /// Adds a word to the spellcheckers dictionary 95. /// </summary> 96. /// <param name="aWord"> 97. /// The word to add to the dictionary 98. /// </param> 99. /// <exception cref="System.ArgumentException"> 100.  /// Thrown when you attempt to add a word to the 101.  /// dictionary that is already in the dictionary 102.  /// </exception> 103.    public void AddToDictionary(String aWord) 104.    { 105.    string lwrCaseWord=aWord.ToLower(); 106.    if (!mDictionary.Contains(107.      lwrCaseWord)) 108.    { 109.      mDictionary.Add(lwrCaseWord); 110.      StreamWriter dictWriter= 111.         new StreamWriter(112.         mDictionaryPath, 113.         true, 114.         System.Text.Encoding.ASCII); 115.      dictWriter.WriteLine(116.      lwrCaseWord); 117.        dictWriter.Close(); 118.    } 119.    else 120.      throw new ArgumentException(121.        aWord + 122.     " already exists in the dictionary", 123.        "aWord"); 124.    } 125.  } 126. } 

On line 2 and 3, I added using statements for the System.Collections.Specialized and System.IO namespaces. Both of these namespaces are implemented in the core system assembly mscorlib.dll. System.Collections.Specialized contains the definition of some specialized collection classes, such as the StringCollection class that I use to hold the dictionary for the spell checker. System.IO contains the definition of the StreamReader class that I use to read the spell checker's dictionary from a disk file and the StreamWriter class that I use to write new entries to the dictionary.

On lines 8 and 9, I declare the class, which I call SpellChecker . Right above the declaration of the class, I have the remarks XML comment that contains a description of the class. On lines 11 through 13, the summary XML comment describes the mDictionary private field of the class (which is declared on line 14) that contains the dictionary of the spell checker. Lines 15 through 18 contain the summary comments and declaration of a field called mDictionaryPath that holds the path to the spell checker's dictionary file. Lines 23 through 32 contain one of the constructors for the SpellChecker class. This constructor has no arguments, and it instantiates a new StringCollection object and then fills it with the contents of the default dictionary file, which is called dictionary.txt and resides in the default directory for the component. Lines 41 through 50 contain the declaration of a second constructor that allows you to specify the path to the dictionary file. This constructor is needed if you are going to use this component on a Web application because you will probably want to locate the dictionary file somewhere beneath the virtual directory for the application. Lines 61 through 74 contain the declaration of a private method called ReadDictionary that populates the mDictionary string collection with the contents from a StreamReader. This method exists to factor out code that is used by both constructors. Lines 85 through 92 contain the declaration of the CheckSpelling method. The implementation of this method is really simple. It converts the specified word to lower-case and then checks if the mDictionary string collection contains the word. If it does, the CheckSpelling method returns true, indicating that the word is correctly spelled. If the word does not exist in the dictionary, the CheckSpelling method returns false, indicating that the word was probably misspelled .

Note

This is obviously a hopelessly simplistic implementation of a spell checker that would be too slow and memory intensive if you had a dictionary of realistic size . If you were implementing a real spell checker, you would probably use a simple database engine to store your dictionary.


Lines 103 through 124 contain the declaration of the AddToDictionary method. This method converts the specified word to lower-case and then checks if the word already resides in the dictionary. If it does, it throws an exception; if it does not, it adds the word to the dictionary. Now that I have implemented the SpellChecker class, the next step is to create a strong name for the assembly.

Adding a Strong Name to the Project

Although it's not a requirement, it's a good idea to give every assembly a strong name. Giving an assembly a strong name allows the CLR to perform more stringent consistency checking, and it allows the eventual consumer of the assembly to put the assembly in the GAC if it wants to. To give an assembly a strong name, you must create a cryptogramic key pair (a public and private key) and then digitally sign your assembly with the private key. Digitally signing an assembly involves creating a hash of the contents of the assembly and then encrypting the hash with the private key from the key pair. When you sign an assembly, you will also insert the public key into the assembly. When you reference an assembly from a client application or component, your compiler will insert this public key into the referencing code. At runtime, the CLR will use the public key to unsign (decrypt) the digital signature. The unsigned digital signature contains the hashed contents of the assembly. The CLR will then rehash the contents of the assembly and compare it to the hash from the digital signature. If the hashes do not match, the assembly was altered since it was built. Assuming the hashes do match, you now know two things: (1) The assembly on disk was authored by the same person who created the assembly that you referenced when you built the client application or component (or at least they have the same private key), and (2) the contents of the assembly were not tampered with after they were compiled. The CLR can only perform these important validity checks if you sign (add a strong name) to the assembly.

You must follow two steps to add a strong name to an assembly:

  1. Create a cryptographic key pair.

  2. Sign the assembly with the key pair.

CREATING A CRYPTOGRAPHIC KEY PAIR

The .NET Framework SDK contains a utility called the Strong Name Tool that you can use to create a cryptographic key pair. The following command line will create a key pair and store it in a file called mykey.snk :

 sn k mykeypair.snk 

The -k option tells the Strong Name Tool to write both the public and private key to the specified file.

Many people may use an organization's public key, but the private key represents the identity of an organization. If it is compromised, other people can do great harm to the organization by doing mischievous or even criminal acts while using the organization's identity. A private key is so sensitive that there are typically only a few people who will ever have it in their possession. Because of this, you may want to separate the public key from the key pair. You can do this using the -p option on the Strong Name Tool. The following command line will extract the public key from the key pair, mykeypair.snk , and save it to a file called publickey .snk :

 sn p mykeypair.snk publickey.snk 

You cannot use a public key alone to "properly" sign an assembly. You must have the private key to create a digital signature. You can use the public key to delay-sign an assembly. I talk about delay signing shortly.

Note

In practice, you won't have to create a new key pair whenever you build a new component. Your company will have a digital key, probably from a Certification Authority (CA) like Verisign.


SIGNING THE ASSEMBLY

You can sign an assembly in two ways: immediately or with delay signing. In order to sign an assembly immediately, you must have both the private and public key. You can sign the assembly at compile time using the AssemblyKeyFile attribute. Usually, you add this attribute to an assemblyinfo file that contains all of your assembly-level attributes as follows:

 [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("..\..\mykey.snk")] 

The parameter for the AssemblyKeyFile attribute specifies the name and location of the file that contains the key pair. The directory for the file is relative to the output location for the compiler, which with Visual Studio .NET is [project directory]\bin\[configuration] , for example, c:\demos\writerstools\bin\debug\ . If you would like to store the key in your root project directory, you would specify "..\\..\\keyfilename" as shown previously. Notice that I have also specified false for the AssemblyDelaySign attribute. Visual Studio .NET uses immediate signing by default, that is, if you do not use the AssemblyDelaySign attribute.

You can also sign an assembly using the assembly linker (al.exe), which is yet another tool in the .NET Framework SDK. To use this approach, you must first use the command-line C# compiler to compile the SpellChecker class into a module and then use the assembly linker to build and digitally sign your assembly. The following command line will create a module from the spellchecker.cs file:

 csc /target:module /out:writerstools.mod spellchecker.cs 

The following command line will build and sign this assembly using the assembly linker and the mykey.snk file that contains the key pair:

 al /out:writerstools.dll writerstools.mod /keyfile:mykey.snk 

If you wish to delay sign your assembly, you will specify true for the parameter to the AssemblyDelaySign attribute as follows:

 [assembly: AssemblyDelaySign(true)] [assembly: AssemblyKeyFile("..\..\publickey.snk")] 

In this case, the specified key file needs only to contain the public key. Remember that the whole purpose of delay signing is to restrict the number of people who have access to the private key of the company. Delay signing inserts the public key into the assembly, which allows developers to write client code that references the assembly. The referencing application or component stores a copy of the public key, which it uses to unsign the digital signature when the application or component runs later. Because a delayed-signed assembly does not have a digital signature, the CLR cannot perform the usual verification (unsigning the digital signature, verifying the hash, and so forth). If you attempt to use an assembly that has been delayed-signed, you will get the following error on your system:

 Strong name validation failed for assembly '[AssemblyName]' 

To use a delay-signed assembly, you must register the assembly for verification skipping on your machine. This lets the CLR know that it should not attempt to perform validation on the assembly. To register your assembly for verification skipping, use the Strong Name Tool with the following command line:

 sn Vr writerstools.dll 

You can now use the assembly on your machine. You must do this for each machine that you want to use the assembly on. When you are ready to ship the assembly, a person who has the private key can use the following command line to sign the assembly properly:

 sn R writerstools.dll mykey.snk 

In this case, mykey.snk is a file that contains both the public and private keys. Now that the assembly is signed, you should unregister the assembly for verification skipping using the following command line:

 sn  -Vu writerstools.dll 

Creating a Windows Forms Client

I'll start using our spell-checker component by creating a Windows Forms client. To create a Windows Forms client, I will perform the following steps:

  1. Create a Visual C# Windows application project.

  2. Draw the UI.

  3. Reference the WritersTools assembly.

  4. Implement the UI.

  5. Compile the application.

  6. Create a dictionary file.

  7. Test.

CREATING A VISUAL C# WINDOWS APPLICATION PROJECT

Start Visual Studio .NET and then execute the following steps:

  1. Select File New Project. The New Project dialog will appear as shown in Figure 5-1.

  2. Select Visual C# Projects under Project Types and then choose Windows Application under Templates.

  3. Change the name of the project to SpellCheckClient.

  4. Select the location where you would like to save the project.

  5. Click OK.

Visual Studio .NET will create a project that initially contains a single form that is the main window of your application. You can drag and drop controls onto this form and then double-click the controls to add handlers for any of the events that the control fires. If you are familiar with VB, you will feel right at home. Before I actually build the UI of the application, let's reference the spell-checker component.

DRAWING THE UI

Using the toolbox in Visual Studio .NET, draw the UI shown in Figure 5-3 on your form.

Figure 5-3. The UI for the Windows Forms client.

graphics/05fig03.jpg

Give the textbox control the following Name: txtWordToCheck. Give the Check Spelling and Add to Dictionary buttons the names cmdCheckSpelling and cmdAddToDictionary, respectively.

REFERENCING THE WRITERSTOOLS ASSEMBLY

With Visual Studio .NET, it's easy to reference and use .NET assemblies. To do this, perform the following steps:

  1. Select Add Reference from the Project menu. The Add Reference dialog will appear as shown in Figure 5-4.

    Figure 5-4. The Add Reference dialog.

    graphics/05fig04.jpg

  2. Click the Browse button (the Select Component dialog will appear) and navigate to where the spell-checker component resides on your system.

  3. Click the Open button.

  4. Click OK on the Add Reference dialog.

You can now use the spell-checker component to implement the UI.

IMPLEMENTING THE UI

In the form designer, double-click the form, which should take you to the handler for the Load method of the form, that is, the method that gets called automatically when the form first loads. Add the following code to this form:

 private void Form1_Load(object sender, System.EventArgs e) {     mSpellChecker=new WritersTools.SpellChecker(); } 

You will also need to add a declaration for the mSpellChecker component to your form class as shown here:

 public class Form1 : System.Windows.Forms.Form { //... code is omitted here for clarity     private WritersTools.SpellChecker mSpellChecker;     public Form1()     {     } //... code is omitted here for clarity } 

Back in the form designer, double-click the CheckSpelling button to add a Click event handler and add the following code:

 private void cmdCheckSpelling_Click(object sender,   System.EventArgs e) {  if (mSpellChecker.CheckSpelling(txtWordToCheck.Text))   MessageBox.Show("Spellcheck complete");   else   MessageBox.Show(txtWordToCheck.Text +   " is misspelled");  } 

Next double-click the Add to Dictionary button and add the following code:

 private void cmdAddToDictionary_Click(object sender,   System.EventArgs e) {   try   {  mSpellChecker.AddToDictionary(   txtWordToCheck.Text);  }     catch (Exception ex)     {       MessageBox.Show(ex.Message);     } } 

Since the AddToDictionary method in the SpellChecker object will throw an exception if you attempt to add a work to the dictionary that is already present, we enclose our call to the AddToDictonary method in a try/catch statement.

CREATING A DICTIONARY FILE

The spell-checker component depends on a dictionary file that must reside in the same directory as its client. Create a text file that contains the following commonly misspelled words (or any words you like) and save it as a text file with the name dictionary.txt in the same directory where you will run the client, for example, C:\DEMOS\CHAP5\SPELLCHECKCLIENT\BIN\DEBUG .

 License Lieutenant Obedient Parliament Surprise Misspelled 

Make sure you put each word on its own line and put a carriage return at the end of each line.

TEST

Congratulations, you have now built your first .NET component and client application using Visual Studio .NET. You can test the application by running the executable. Type in one of the words that is currently in the dictionary, and you will see a message box that says "Spell check complete". Type in any other word, and you will see a message box that says "[word] is misspelled". If you click the button that says "Add to dictionary", the word will be added to the dictionary. The next time that you check spelling on that word, you will see the Spell check complete dialog. Next, I create a Web Forms client.

Creating a Web Forms Client

Web Forms is a .NET technology that makes it as easy to create Web-based UIs as it is to create forms-based Windows applications using VB. Web Forms are a part of Microsoft's ASP.NET technology, which also encompasses the infrastructure for Web services. The key to Web Forms is server controls, which are components that typically have both a runtime and a design time visual representation. You place these controls on a form, set their properties, and handle their events to determine how they will look and behave. At run-time when a user makes a request, the ASP.NET runtime renders an HTML representation of the server control to the client. Server controls are smart enough to render HTML that is browser independent, that is, a Web Forms application that will run on Internet Explorer, Netscape, or another other browser that supports HTML 3.2 as a minimum. Server controls are also smart enough to take advantage of the capabilities of up-level browsers, like scripting. Let's see how simple it is to build a client application for the spell-checker component using Web Forms. To build the application, I will perform the following steps:

  1. Create a Visual C# ASP.NET Web application project.

  2. Draw the UI.

  3. Reference the WritersTools assembly.

  4. Implement the UI.

  5. Create a dictionary file.

  6. Test the application.

CREATING A VISUAL C# ASP.NET WEB APPLICATION PROJECT

Start Visual Studio .NET and then execute the following steps:

  1. Select File New Project. The New Project dialog will appear as shown in Figure 5-1.

  2. Select Visual C# Projects under Project Types and then choose ASP.NET Web Application under Templates.

  3. Change the location of the project to http://localhost/SpellCheckWebClient.

  4. Click OK.

Visual Studio .NET will create a new virtual directory for the application at the location that you specified. The physical location of the virtual directory is the following:

 [Inetpub]\wwwroot\SpellCheckWebClient 

Visual Studio .NET will create a project at this location that contains a single form that is the main window of your application. The difference is that now this form is an ASP.NET Web page with the name WebForm1.aspx as shown in Figure 5-5. You can drag and drop controls onto this form and then double-click the controls to add handlers for any of the events that the control fires, just as you did with the Windows Forms application. Once again, if you are familiar with VB, you will feel right at home.

Figure 5-5. An ASP.NET Web application project in Visual Studio.NET.

graphics/05fig05.jpg

DRAWING THE UI

Using the toolbox in Visual Studio .NET, draw the UI shown in Figure 5-6 on your form.

Figure 5-6. The UI for the Web Forms client in Visual Studio .NET.

graphics/05fig06.jpg

Give the text box the name txtWordToCheck. The red "lblResponse" text that you see in Figure 5-6 is a label with the name lblResponse and the forecolor property set to red. As before, give the Check Spelling button the name cmdCheckSpelling and use cmdAddToDictionary for the name of the Add to Dictionary button. Before I implement the UI of the application, let's reference the spell-checker component.

REFERENCING THE WRITERSTOOLS ASSEMBLY

The steps to reference a .NET assembly from a Web Forms application are exactly the same as the steps for a Windows Forms application, so I won't repeat them here. Refer back to the section with the same name in the steps for building a Windows Forms application.

IMPLEMENTING THE UI

Implement the UI for the Web Forms client by double-clicking the Check Spelling button on the main form of the application. This will create an empty click event handler for the button. Add the following code to the event handler:

 private void cmdCheckSpelling_Click(object sender,   System.EventArgs e) {   WritersTools.SpellChecker spellChecker;   string strDictionaryPath=     Request.PhysicalApplicationPath +     "dictionary.txt";   spellChecker=new WritersTools.SpellChecker     (strDictionaryPath);   if (spellChecker.CheckSpelling(txtWordToCheck.Text))     lblResponse.Text="Spellcheck complete";   else     lblResponse.Text=txtWordToCheck.Text +       " is misspelled"; } 

Notice that I create a new instance of the SpellChecker component each time the user clicks the Check Spelling button. With ASP.NET Web Forms, a new instance of the page class is created to service each request, so we must create a SpellChecker object each time. An alternative is to cache the SpellChecker in the ASP.NET session object.

Next double-click the Add to dictionary button on the main form and add the following code to the click event handler for that button:

 private void cmdAddToDictionary_Click(object sender,   System.EventArgs e) {   try   {     WritersTools.SpellChecker spellChecker;     string strDictionaryPath=       Request.PhysicalApplicationPath +       "dictionary.txt";     spellChecker=new WritersTools.SpellChecker       (strDictionaryPath);     spellChecker.AddToDictionary(txtWordToCheck.Text);     lblResponse.Text=txtWordToCheck.Text +       " has been added to the dictionary";   }   catch(ArgumentException argEx)   {     lblResponse.Text=txtWordToCheck.Text +       " already exists in the dictionary";   }   catch(Exception ex)   {     lblResponse.Text=       "The following error occurred: " +       ex.Message;   } } 
CREATING A DICTIONARY FILE

You will also need to create a dictionary file and copy it to the virtual directory for the application. The easiest thing to do is to just copy the dictionary.txt file that you built for the Windows Forms client earlier. Copy this text file to the root directory of your Web application. On my machine, this was D:\Inetpub\wwwroot\SpellCheckWebClient\ .

TESTING THE APPLICATION

To test the application, open up Internet Explorer and type the following URL into your browser: http://localhost/SpellCheckWebClient/WebForm1.aspx.

Note

This URL assumes that you did not rename your initial Web Form, which has the name WebForm1.aspx.


You should see the UI in Figure 5-7 in Internet Explorer.

Figure 5-7. The Web Forms client in Internet Explorer.

graphics/05fig07.jpg

You can enter a word to spell check and click the Check Spelling button. If a word is not found in the dictionary, you can click the Add to Dictionary button, and it will add the word to the dictionary so that, the next time you spell check the word, it will find it.


Team-Fly    
Top
 


. Net and COM Interoperability Handbook
The .NET and COM Interoperability Handbook (Integrated .Net)
ISBN: 013046130X
EAN: 2147483647
Year: 2002
Pages: 119
Authors: Alan Gordon

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net