Articles in this section
Category / Section

How to use EJSpellChecker in your application

4 mins read

Description:

You can render EJ SpellCheck with dictionary settings defined in a WebAPI Controller.

Solution:

After installing our Essential Studio® build, the required assemblies and scripts will be shipped inside the installed location. Refer to the Syncfusion.EJ, Syncfusion.EJ.MVC, and Syncfusion.SpellChecker.Base assemblies from installed location into your project.

The following screenshot illustrates assembly reference.

http://www.syncfusion.com/downloads/support/directtrac/230633/2099129334_937d377f.PNG

Also, you need to register these assembly details in Web.config with version.

<assemblies>

        <add assembly="Syncfusion.SpellChecker.Base, Version=17.1450.0.38, Culture=neutral, PublicKeyToken=3d67ed1f87d44c89" />

        <add assembly="Syncfusion.EJ, Version=17.1450.0.38, Culture=neutral, PublicKeyToken=3d67ed1f87d44c89" />

        <add assembly="Syncfusion.EJ.Mvc, Version=17.1500.0.38, Culture=neutral, PublicKeyToken=3d67ed1f87d44c89" />

 </assemblies>

 

Refer to the scripts and CSS in the master page of the project.

<head> 
    <meta charset="utf-8" /> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <title>@ViewBag.Title - My ASP.NET Application</title> 
    @Styles.Render("~/Content/css") 
    @Styles.Render("~/Content/ej/web/default-theme/ej.web.all.min.css") 
    @Scripts.Render("~/bundles/modernizr") 
    @Scripts.Render("~/Scripts/jquery-3.2.1.min.js") 
    @Scripts.Render("~/Scripts/jsrender.min.js") 
    @Scripts.Render("~/Scripts/ej/ej.web.all.min.js")     
</head> 
 

Add the following code for rendering EJ SpellCheck and specify the WebAPI path for dictionary reference.

<div id="ControlRegion">
    <div>
        <div>
            <div id="TextArea" contenteditable="true">
                Facebook is a social networking service headquartered in Menlo Park, California. Its website was launched on February 4, 2004, by Mark Zuckerberg with his Harvard College roommates and fellow students Eduardo, Andrew McCollum, Dustin, and Chris Hughes.
                The founders had initially limited the websites membership to Harvard students, but later expanded it to colleges in the Boston area, the Ivy League, and Stanford University. They gradually added support for students at various other universities and later to high-school students.
            </div>
            <div>
                <input type="button" id="SpellCheck" />
            </div>
            <script type="text/javascript">
                $(function () {
                    $("#TextArea").ejSpellCheck({
                        dictionarySettings: {
                            dictionaryUrl: "../api/SpellCheck/CheckWords"//default dictionary WebAPI path
                            customDictionaryUrl: "../api/SpellCheck/AddToDictionary" //custom dictionary WebAPI path
                        },
                        contextMenuSettings: { enable: false }
                    });
                    $("#SpellCheck").ejButton({ click: "showDialog", text: "Spell check using dialog" });
                });
 
                function showDialog() {
                    var spellObj = $("#TextArea").data("ejSpellCheck");
                    spellObj.showInDialog();
                }
            </script>
        </div>
    </div>
</div>
 

Add the following code in WebAPI controller to perform spell check.

public class SpellCheckController : ApiController
    {
        internal SpellCheckerBase baseDictionary, customDictionary;
 
        private readonly string _customFilePath = HttpContext.Current.Server.MapPath("~/App_Data/Custom.dic"); // Here we need to specify the corresponding file name for custom dictionary
        private readonly List<Status> errorWords = new List<Status>();
 
        SpellCheckController()
        {
            if (baseDictionary == null)
            {
                string filePath = HttpContext.Current.Server.MapPath("~/App_Data/Default.dic");
                // Here we need to specify the corresponding file name for dictionary
                Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                baseDictionary = new SpellCheckerBase(stream);
            }
            this.CustomFileRead();
        }
 
        #region helpers
        private void CustomFileRead()
        {
            Stream stream1 = new FileStream(_customFilePath, FileMode.Open, FileAccess.ReadWrite);
            customDictionary = new SpellCheckerBase(stream1);
        }
        private bool CheckWord(string word)
        {
            var flag = false;
            if (baseDictionary.HasError(word))
            {
                flag = true;
                using (StreamReader sr = new StreamReader(_customFilePath))
                {
                    var contents = sr.ReadToEnd();
                    if (contents != "")
                    {
                        flag = customDictionary.HasError(word) ? true : false;
                    }
                }
            }
            return flag;
        }
}

Add the following code for adding words to custom dictionary.

 
        private void AddToCustomDictionary(string word)
        {
            using (System.IO.StreamWriter file = new System.IO.StreamWriter(_customFilePath, true))
            {
                file.Write(word + Environment.NewLine);
            }
            this.CustomFileRead();
        }
 

Add the following code for adding words to the default dictionary.

        [AcceptVerbs("Get", "Post")]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public object AddToDictionary(string callback, string data)
        {
            var serializer = new JavaScriptSerializer();
            Actions args = (Actions)serializer.Deserialize(data, typeof(Actions));
            if (args.CustomWord != null)
            {
                this.AddToCustomDictionary(args.CustomWord); // add custom words
            }
            HttpContext.Current.Response.Write(string.Format("{0}({1});", callback, serializer.Serialize(args.CustomWord)));
            return string.Empty;
        }
 

Check words and get suggestions.

       [AcceptVerbs("Get", "Post")]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public object CheckWords(string callback, string data)
        {
            var serializer = new JavaScriptSerializer();
            Actions args = (Actions)serializer.Deserialize(data, typeof(Actions));
 
            if (args.RequestType == "checkWords")
            {
                baseDictionary.IgnoreAlphaNumericWords = args.Model.IgnoreAlphaNumericWords;
                baseDictionary.IgnoreEmailAddress = args.Model.IgnoreEmailAddress;
                baseDictionary.IgnoreMixedCaseWords = args.Model.IgnoreMixedCaseWords;
                baseDictionary.IgnoreUpperCaseWords = args.Model.IgnoreUpperCase;
                baseDictionary.IgnoreUrl = args.Model.IgnoreUrl;
                baseDictionary.IgnoreFileNames = args.Model.IgnoreFileNames;
                var errorWords = this.SplitWords(args.Text);
                HttpContext.Current.Response.Write(string.Format("{0}({1});", callback, serializer.Serialize(errorWords)));
            }
            else if (args.RequestType == "getSuggestions")
            {
                var suggestions = baseDictionary.GetSuggestions(args.ErrorWord);
                HttpContext.Current.Response.Write(string.Format("{0}({1});", callback, serializer.Serialize(suggestions)));
            }
            return string.Empty;
        }
 

Get the status of error words.

        private List<Status> GetStatus(string textWord)
        {
            var splitWords = Regex.Replace(textWord, @"[^0-9a-zA-Z\'_]", " ").Split(null);
            foreach (var inputWord in splitWords)
            {
                if (this.CheckWord(inputWord))
                {
                    errorWords.Add(new Status
                    {
                        ErrorWord = inputWord
                    });
                }
            }
            return errorWords;
        }

Split the words using regex for checking error words.

private List<Status> SplitWords(string text)
        {
            var words = text.Split(null);
            foreach (var word in words)
            {
                string textWord;
                Uri uriResult;
                bool checkUrl = Uri.TryCreate(word, UriKind.Absolute, out uriResult)
                              && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
                if (checkUrl)
                {
                    textWord = word;
                    if (this.CheckWord(textWord))
                    {
                        this.GetStatus(textWord);
                    }
                }
                else if (Regex.IsMatch(word,
                    @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +
                    @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$",
                    RegexOptions.IgnoreCase))
                {
                    textWord = word;
                    if (this.CheckWord(textWord))
                    {
                        this.GetStatus(textWord);
                    }
                }
                else if (Regex.IsMatch(word, @"[a-zA-Z0-9_$\-\.\\]*\\[a-zA-Z0-9_$\-\.\\]+"))
                {
                    textWord = word;
                    if (this.CheckWord(textWord))
                    {
                        this.GetStatus(textWord);
                    }
                }
                else
                {
                    if (word.EndsWith(".") || word.EndsWith(","))
                    {
                        textWord = word.Remove(word.Length - 1);
                    }
                    else if (word.Contains('\t') || word.Contains('\n') || word.Contains('\r'))
                    {
                        textWord = Regex.Replace(word, @"\t|\n|\r", "");
                    }
                    else
                    {
                        textWord = word;
                    }
                    this.GetStatus(textWord);
                }
            }
            return errorWords;
        }
 

The sample can be downloaded from the following link: Sample

Note:

The dictionaries can be backed up, and they can be used in multiple environments by specifying the path of the file in WebApi Controller.  

 

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (3)
Please  to leave a comment
AM
Alexander Mihail

Good day, Fellows,

I have tried the tutorial on this page and it works in most its aspects except SpellCheckBase.HasError(word) that always returns true. It feels like neither Default.dic, nor Custom.dic are loaded by the SpellCheckBase logic. My simplest code sample follows.

Regards.

SpellCheckController() { if (baseDictionary == null) { string filePath = HttpContext.Current.Server.MapPath("~/App_Data/Default.dic"); // Here we need to specify the corresponding file name Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);

    // added a test to prove that stream access is okay
    byte[] b = new byte[stream.Length]; 
    stream.Read(b, 0, (int)stream.Length);
    stream.Seek(0, SeekOrigin.Begin);

    baseDictionary = new SpellCheckerBase(stream);

    // Words in Default.dic are always in error, probably never matched. Why?
    if (baseDictionary.HasError("this"))
      ;  // test is always true, why?

}
this.CustomFileRead();

}

MK
Muthukrishnan Kandasamy

Hi Alexander,

Greetings from Syncfusion support.

We have validated your reported problem in SpellCheck control. We were unable to reproduce your reported problem in SpellCheck control. We suspect that in your project dictionary files were not loaded properly. If the dictionary file contains the specific word then that condition will return false, otherwise if the word not exist in the dictionary then condition will become true. Please check the below screenshot.

enter image description here

We have prepared sample for your convenience, please refer to the below link for the sample.

https://www.syncfusion.com/downloads/support/directtrac/general/ze/SpellCheckMVC343863676

Please add necessary dll for SpellCheck service operations. Please refer to the below dll,

• Syncfusion.EJ • Syncfusion.EJ.MVC • Syncfusion.SpellChecker.Base

You can get dependent package Syncfusion.SpellChecker.Base dll in below location. Please find it below.

C:\Program Files (x86)\Syncfusion\Essential Studio{Product Version}\Assemblies\Based on your Assembly version\

(e.g) C:\Program Files (x86)\Syncfusion\Essential Studio\18.1.0.52\Assemblies\4.5\Syncfusion.SpellChecker.Base.dll

Or else, you can refer the following help document to install the spell checker package in your application.

https://www.nuget.org/packages/Syncfusion.SpellChecker.Base/

Getting started: https://help.syncfusion.com/aspnetmvc/spellcheck/getting-started

Dictionary: https://help.syncfusion.com/aspnetmvc/spellcheck/dictionary

Functionality: https://help.syncfusion.com/aspnetmvc/spellcheck/functionalities

API reference: https://help.syncfusion.com/api/js/ejspellcheck

Live demo: https://mvc.syncfusion.com/demos/web/spellcheck/default

Please let us know, if you need any further assistance.

Regards, Muthukrishnan K

RM
Rishi Malviya

sdasda

Access denied
Access denied