The Bing Spell Check API leverages the power of machine learning and statistical machine translation to train and evolve a highly contextual algorithm for spellchecking. Doing so allows us to utilize this to perform spellchecking using context.
A typical spellchecker will follow dictionary-based rule sets. As you can imagine, this will need continuous updates and expansions.
Using the Bing Spell Check API, we can recognize and correct slang and informal language. It can recognize common naming errors and correct word-breaking issues. It can detect and correct words that sound the same, but differ in meaning and spelling (homophones). It can also detect and correct brands and popular expressions.
Create a new View
in the View
folder; call the file SpellCheckView.xaml
. Add a TextBox
element for the input query. We will also need two TextBox
elements for the pre- and post-context. Add a TextBox
element to show the result and a Button
element to execute the spellcheck.
Add a new ViewModel
in the folder named ViewModel
; call the file SpellCheckViewModel.cs
. Make the class public
, and let it inherit from the ObservableObject
class. Add the following private
member:
private WebRequest _webRequest;
This is the WebRequest
class that we created earlier.
We need properties corresponding to our View
. This means that we need four string
properties and one ICommand
property.
If you have not already done so, register for a free API key at https://portal.azure.com.
The constructor should look like the following:
public SpellCheckViewModel() { _webRequest = new WebRequest ("https://api.cognitive.microsoft.com/bing/v7.0/spellcheck/?", "API_KEY_HERE"); ExecuteOperationCommand = new DelegateCommand( ExecuteOperation, CanExecuteOperation); }
We create a new object of a WebRequest
type, specifying the Bing Spell Check API endpoint and the API key. We also create a new DelegateCommand
for our ExecuteOperationCommand
, ICommand
, property.
The CanExecuteOperation
property should return true
if our input query is filled in and false
otherwise.
To execute a call to the API, we do the following:
private async void ExecuteOperation(object obj) { var queryString = HttpUtility.ParseQueryString(string.Empty); queryString["text"] = InputQuery; queryString["mkt"] = "en-us"; //queryString["mode"] = "proof"; if (!string.IsNullOrEmpty(PreContext)) queryString["preContextText"] = PreContext; if(!string.IsNullOrEmpty(PostContext)) queryString["postContextText"] = PostContext;
First, we create a queryString
using HttpUtility
. This will format the string so that it can be used in a URI.
As we will be calling the API using a GET
method, we need to specify all parameters in the string. The required parameters are text
and mkt
, which are the input query and language, respectively. If we have entered PreContext
and/or PostContext
, then we add these parameters as well. We will look at the different parameters in more detail in a bit.
To make the request, we need to make the following call:
SpellCheckResponse response = await _webRequest.MakeRequest <object, SpellCheckResponse>(HttpMethod.Get, queryString.ToString()); ParseResults(response); }
We call MakeRequest
on the _webRequest
object. As we are making a GET
request, we do not need any request body, and we pass on object
as TRequest
. We expect a SpellCheckResponse
contract in return. This will contain the resultant data, and we will look at the parameters in greater detail in a bit.
When we have a response, we pass that on to a function to parse it, as shown in the following code:
private void ParseResults(SpellCheckResponse response) { if(response == null || response.flaggedTokens == null || response.flaggedTokens.Count == 0) { Result = "No suggestions found"; return; } StringBuilder sb = new StringBuilder(); sb.Append("Spell checking results:nn");
If we do not have any response, we exit the function. Otherwise, we create a StringBuilder
to format the results, as shown in the following code:
foreach (FlaggedTokens tokens in response.flaggedTokens) { if (!string.IsNullOrEmpty(tokens.token)) sb.AppendFormat("Token is: {0}n", tokens.token); if(tokens.suggestions != null || tokens.suggestions.Count != 0) { foreach (Suggestions suggestion in tokens.suggestions) { sb.AppendFormat("Suggestion: {0} - with score: {1}n", suggestion.suggestion, suggestion.score); } sb.Append("n"); } } Result = sb.ToString();
If we have any corrected spellings, we loop through them. We add all suggestions to the StringBuilder
, making sure that we add the likelihood of the suggestion being correct. At the end, we make sure that we output the result to the UI.
The following table describes all the parameters we can add to the API call:
Parameter |
Description |
---|---|
|
The text that we want to check for spelling and grammar errors. |
|
The current mode of the spellcheck. It can be either of the following:
|
|
The string that gives context to the text. The petal parameter is valid, but if you specify bike in this parameter, it will be corrected to pedal. |
|
The string that gives context to the text. The read parameter is valid, but if you specify carpet in this parameter, it may be corrected to red. |
|
For proof mode, the language must be specified. It can currently be en-us, es-es, or pt-br. For spell mode, all language codes are supported. |
A successful response will be a JSON response, containing the following:
{ "_type": "SpellCheck", "flaggedTokens": [ { "offset": 5, "token": "Gatas", "type": "UnknownToken", "suggestions": [ { "suggestion": "Gates", "score": 1 }] }] }
The offset
is where the word appears in the text and token
is the word that contains the error, while type
describes the type of error. The suggestions
phrase contains an array with the suggested correction and the probability of it being correct.
When the View
and ViewModel
have been correctly initialized, as seen in previous chapters, we should be able to compile and run the example.
An example output of running a spellcheck may give the following result: