Introduction
SharePoint is Microsoft’s server dedicated to the interchange of information and thus a system where writing is a critical component. As with other Office family products, Microsoft Office SharePoint Server (MOSS) provides tools to check and correct the orthography in texts. The service is used in some default components of MOSS, allowing developers to utilize it in custom software, such as WebParts or specialized pages.
The SharePoint Object Model offers spell check as a WebService to control the orthography in different languages, providing suggestions and alternatives to correct errors. It’s important to point out that the service is not equal to the system used by other Office products. Consequently—as an on-line server—the SharePoint system is less advanced, and provides limited functionality in contrast to the default spell check of Word or Excel; for example, there is no possibility to check grammar nor does it offer a thesaurus.
MOSS uses spell check in various locations; for example, in each List where there are Text Fields there is a “Spelling” button in the horizontal tools bar. When you click the button, a popup window appears, allowing you to loop through the words on the page, making a comparison with the internal dictionary and displaying words with errors, together with suggestions to rectify them.
Figure 1: SharePoint List with the Spelling button and popup window
The same window allows users to select the Language and Dialect for the corrector (the configured default Language is initially used). The corrector only compares words with the internal dictionary, without grammar or syntax corrections. Another disadvantage is that it is not possible to add new words to the dictionary; to circumvent that situation, a list of words can be created that will be ignored by the corrector; in fact, it’s a specially designed dictionary.
WebService
All the corrector’s functionality is available as a default Microsoft Office SharePoint Server (MOSS) WebService. The “SpellCheck.asmx” WebService has three input parameters:
- chunksToSpell: An array of strings with the texts to check
- declaredLanguage: An integer that gives the Language Identifier to be used by the checker. This Identifier is not the same as that used by SharePoint for its internal configuration; the values can be found on the Microsoft site http://msdn2.microsoft.com/en-us/library/0h88fahh.aspx; use the value of the column “Decimal value”
- useLad: A Boolean that indicates whether the spell check should detect the MOSS default language
At first glance, the WebService is very straightforward to apply following a simple sequence: create a reference, give the service user credentials, configure the input parameters, and execute the service. Unfortunately, the MOSS implementation has two crucial errors that hamper its use.
First, if the parameter “useLad” is employed in such a way that spell check uses the default MOSS language, the checker will apply the Language Identifier of MOSS, not the target Language Identifier to be checked. This is not a problem in English, because the two Language Identifiers are the same (1033), but in other languages it is always different. For example, in Spanish the WebService will use 3082 (MOSS Language Identifier for Spanish) instead of 1034 (Language Identifier for Spanish Spell Check). Consequently, the corrector never provides accurate results in languages other than English.
To avoid this problem, declare the “useLad” parameter as false and give the correct Language Identifier in the “declaredLanguage” parameter. The downside to this workaround is that you always need to use a constant identifier or you must create a lookup table with the necessary logic to link the MOSS Language Identifier to the spell check Language Identifier.
The second problem may be more serious. Because the WebService has irregularities in the code, vocabulary suggestions are not provided. To resolve this problem, it is obligatory to call the WebService using the methods of the class “HttpWebRequest” from the NameSpace “System.Net”, creating the SOAP envelope and XML query manually, as outlined in the following paragraphs.
In the source code where the WebService will be called, create references (“using” in CSharp) to System, System.IO, System.Net, System.Text and System.Xml. The following code lines call the WebService using the HttpWebRequest class:
StringBuilder myStringBuilder = new StringBuilder(EnvelopeSoap); myStringBuilder.Insert(myStringBuilder.ToString(). IndexOf("</soap:Body>"), MyQuery); XmlDocument EnvelopeSoapXml = new XmlDocument(); EnvelopeSoapXml.LoadXml(myStringBuilder.ToString()); HttpWebRequest myQueryWeb = (HttpWebRequest)WebRequest.Create(UrlChequerWS); myQueryWeb.UseDefaultCredentials = true; myQueryWeb.Headers.Add("SOAPAction", AccionSoap); myQueryWeb.ContentType = "text/xml;charset="utf-8""; myQueryWeb.Accept = "text/xml"; myQueryWeb.Method = "POST"; using (Stream myStream = myQueryWeb.GetRequestStream()) { EnvelopeSoapXml.Save(myStream); } IAsyncResult ResultAsync = myQueryWeb.BeginGetResponse(null, null); ResultAsync.AsyncWaitHandle.WaitOne(); string ResponseSoap = string.Empty; using (WebResponse ResponseWeb = myQueryWeb.EndGetResponse(ResultAsync)) using (StreamReader myStreamReader = new StreamReader(ResponseWeb.GetResponseStream())) { ResponseSoap = myStreamReader.ReadToEnd(); }
In the code, create a StringBuilder that contains the SOAP call to the WebService. The SOAP envelope is directly added by using the following syntax:
static string EnvelopeSoap = @"<soap:Envelope xmlns_xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns_xsd='http://www.w3.org/2001/XMLSchema' xmlns_soap='http://schemas.xmlsoap.org/soap/envelope/'> <soap:Body></soap:Body> </soap:Envelope>";
Then, immediately before closing the envelope, add the XML query with the following syntax:
static string MyQuery = @"<SpellCheck > <chunksToSpell> <string>This rou</string> <string> has an error </string> </chunksToSpell> <declaredLanguage>1033</declaredLanguage> <useLad>false</useLad> </SpellCheck>";
There are two strings in the query that need to be adjusted, namely “This rou” and “has an error”, the Language Identifier is declared (1033) and the MOSS Language Identifier must be blocked with the code; useLead=false. As stated earlier, at this point you need to define the spell check Language Identifier if you are using a language other than English.
After the creation of the envelope and the query in a string, they are converted to a XmlDocument that can be used in the service call. The object “myQueryWeb” (of the “HttpWebRequest” type) is created using as input parameter the URL of the spell check WebService:
static string UrlChequerWS = "http[s]://ServerName/_vti_bin/SpellCheck.asmx";
The object receives the default credentials of the user, the content type, the type of the method to be used, and finally, the form to send the envelope. The SOAP action type is added to the header in the following manner:
static string AccionSoap = "http://schemas.microsoft.com/sharepoint/publishing/ spelling/SpellCheck";
With this action, the envelope is assigned to the WebService call and using the interface, IAsyncResult, the anticipated result is asynchronous; this avoids a delay in the functioning of SharePoint while awaiting the response.
Finally, the call to the WebService is executed and the results come back in the form of a “WebResponse” object that is converted to a “StreamReader” that needs to be interpreted; the final result is a XML string, “ResponseSoap”. The response of the example is in the form:
<?xml version="1.0" encoding="utf-8" ?> - <soap:Envelope xmlns_soap= "http://schemas.xmlsoap.org/soap/ envelope/" xmlns_xsi="http://www.w3.org/2001/ XMLSchema-instance" xmlns_xsd="http://www.w3.org/2001/XMLSchema"> - <soap:Body> - <SpellCheckResponse > - <SpellCheckResult> <errorCode>Ok</errorCode> <detectedLanguage>1033</detectedLanguage> - <spellingErrors> - <SpellingErrors> <chunkIndex>0</chunkIndex> - <flaggedWords> - <FlaggedWord> <word>rou</word> <type>UnknownWord</type> <offset>3</offset> </FlaggedWord> </flaggedWords> </SpellingErrors> </spellingErrors> - <spellingSuggestions> - <SpellingSuggestions> <word>rou</word> - <sug> <string>roue</string> <string>rout</string> <string>roux</string> <string>roe</string> <string>row</string> <string>rob</string> </sug> </SpellingSuggestions> </spellingSuggestions> </SpellCheckResult> </SpellCheckResponse> </soap:Body> </soap:Envelope>
In the SOAP response, note that the corrector—in the first string (chunkIndex=0)—has identified an unknown word (FlaggedWord-word=rou), that probably has an error in the third character (offset=3). The suggestions section indicates that the unidentified word has six possible corrections in the dictionary. The second string is not found in the response, signifying it is accepted by the corrector.
The remaining code implementation is elemental and can be used in each SharePoint component (WebParts, WebControls, Web pages, and so forth). The last task is to extract the relevant information from the XML response and present it to the user in the desired way.
Spell Check Default Components
It is not necessary to use WebService spell check directly, as indicated in the last section; it is also possible to use the existing SharePoint default infrastructure for this purpose. The default implementation of spell check for MOSS is based in one ASPX page and two JavaScript files:
- SpellChecker.aspx: (C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12TEMPLATELAYOUTSSpellChecker.aspx) contains the Web page used to show words with errors and the suggestions (shown in Figure 1)
- SpellChecker.js: (C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12TEMPLATELAYOUTS3082SpellChecker.js) contains the routines to call the WebService, show and rectify words with errors
- SpellCheckerEntirePage.js: (C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12TEMPLATELAYOUTS3082SpellChecker.js) works as a link between the aspx page and the routines of the JavaScript in SpellChecker.js.
In the event the Language cannot be detected, the ASPX page initially shows a menu to select it from the available Languages List.
The default MOSS corrector page can be initiated from each ASPX page as well. To view the process, create a new file with the .aspx extension (“spellcheck.aspx”, for example) in the directory “C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12TEMPLATELAYOUTS”. Open the file with any ASCII text editor (Notepad) and add a reference to the SharePoint assembly:
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
Then, create references to the files with the JavaScripts:
<SharePoint:ScriptLink language="javascript" name="core.js" runat="server" /> <SharePoint:ScriptLink language="javascript" name="SpellCheckEntirePage.js" runat="server" />
And a JavaScript section to call Spell Check:
<script language="javascript" type="text/javascript"> function CheckSpell() { SpellCheckEntirePage('/_vti_bin/SpellCheck.asmx', '/_layouts/SpellChecker.aspx'); } </script>
Finally, create the content controls where the user can write a text to be checked. In the example, it is one text box, but as many as are required can be created and spell check will loop through all of them scanning for errors. Use the syntax:
Some text to check <input type="text" name="SomeText"> <br><br>
The button at the end will call the JavaScript and spell check:
<a href="javascript:" onclick="CheckSpell();">Spell Checker</a>
Call the aspx from MOSS using the URL (http[s]://ServerName/_layouts/ spellcheck.asp). After clicking the button, a popup window will appear, showing the incorrect words and the correction suggestions:
Figure 2: ASPX custom page using default spell check
With the preceding code, all the texts found on the page will be scanned. If you want to exclude any of the text from correction, use the attribute “excludeFromSpellCheck” in the HTML syntax. For example, to create a text box controlled by the server where no spell check is desired, use:
<asp:TextBox ID="TextBoxNoControled" runat="server" excludeFromSpellCheck="true" />
Note: The “excludeFromSpellCheck” attribute can be used in a similar way in client-side controls by using HTML code.
If necessary, it also is possible to modify the files SpellChecker.aspx, SpellChecker.js and/or SpellCheckerEntirePage.js, but it is not recommended or effective because any future Microsoft Service Pack can revert the files to the original state.
Dictionary Modifications
MOSS has default correction dictionaries for each supported language, but it is impossible to modify them. However, it is possible to add words in such a way that they are not identified as errors. The following process creates a type of custom dictionary for these words:
- Create a new Document Library, “Spelling,” at the root of the Portal.
- Create a text file, “Custom Dictionary.txt,” locally.
- Add all the words that should not be recognized as spelling errors in the text file, one word per line.
- Upload the text file to the newly created Library above.
Only one “Custom Dictionary” Document Library is possible for each site collection; the names of the Library and text file need to be exactly as indicated and the Library must be located at the root of the Portal.
Conclusion
A valuable feature of SharePoint 2007 is the introduction of an online spell check program. The system is presented as a WebService, but the feature has some errors that need workarounds to function properly.
Spell Check is a default component of Microsoft Office SharePoint Server (MOSS) but is not available in Windows SharePoint Services (WSS). The system is a welcome adaption and covers the supported SharePoint Languages. It is effective for detecting orthography errors and provides correction suggestions; however, the downside is that it lacks a grammar and a thesaurus and the dictionaries cannot be modified.
The default window of the corrector can be used in custom components inside SharePoint, as ASPX pages, with the inclusion of a few lines of code. Finally, although the dictionaries cannot be modified, it is possible resolve this inadequacy by creating a list of words to be excluded from Spell Check control.
About the Author
Gustavo Velez is a MCSD Senior Application Developer for Winvision (http://www.winvision.nl), a Microsoft Gold Partner in the Netherlands. He has many years experience developing Windows and Office applications, and more than six years of daily programming experience with SharePoint. The author’s articles can be found in many of the leading trade magazines in English, Dutch, and Spanish. He is also pleased to be Webmaster of http://www.gavd.net/servers, the only Spanish-language site dedicated to SharePoint. Spanish-language readers may want to consult Velez’s book; Programacisn con SharePoint 2007 (http://www.dotnetmania.com/Libros/index.html). Velez has been awarded MVP status (Most Valuable Professional, http://mvp.support.microsoft.com/), in the area of SharePoint MOSS.