Search code examples
c#.netxmlxml-documentation

How can I make Web/API help in multiple languages?


Scenario:

I'm working with C# and Web API 2.1 in Visual Studio .NET 2012.

I'm commenting the code with the default option in /// like this:

    /// <summary>
    /// This method get something and returns something.
    /// </summary>
    /// <returns>HttpResponseMessage response etc etc</returns>
    public HttpResponseMessage Get() {

I setted up the XML Documentation File (in the build properties) and then I get the information file and show them in the api service help with this line (as come from VS)

        //// Uncomment the following to use the documentation from XML documentation file.
        config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/myXMLFile.XML")));

So far so good, I can read successfully the XML file in the Help Area. But....


Problem:

My clients will read this HELP file as second documentation in order to connect and use my exposed services trough web api. But the requirement is that the help must be in several languages, english, spanish, german and so on.

I was thinking in make some "language selector" in the home of the Web Api Help Area, but I can't realize how make multiple comments, multiple XML files or something related.

I was researched but I only found information about Sandcastle (I never use it) and I'm wonder myself if it's possible doing only with Visual Studio or some Nuget Package App.


Question:

In resume:

Is this possible comment the code with several languages and having several XML files, and select them from Help Area page?

Thanks in advance. Please comment/edit/review, I'll glad to improve my question.


Update 1 (2014-11-06 03:11 UTC)

At this time I'm working trying to modify this function but I can't change/take the value lang of an attribute tag.

(at XmlDocumentationProvider in Project\Areas\HelpPage\):

public virtual string GetDocumentation(HttpActionDescriptor actionDescriptor)
{
    XPathNavigator methodNode = GetMethodNode(actionDescriptor);
    if (methodNode != null)
    {
        XPathNavigator summaryNode = methodNode.SelectSingleNode("summary");
        if (summaryNode != null)
        {
            return summaryNode.Value.Trim();
        }
    }

    return null;
}

Solution

  • I will assume that your documentation documentation is something like this

    /// <summary>
    /// Looks up some data by ID.
    /// </summary>
    /// <summary xml:lang="es">
    /// Recupera algun dato por id.
    /// </summary>
    public string Get(int id)
    {
        return "value";
    }
    

    So my approximation is this:

        public virtual string GetDocumentation(HttpActionDescriptor actionDescriptor)
        {
            XPathNavigator methodNode = GetMethodNode(actionDescriptor);
            if (methodNode != null)
            {
                XPathNavigator summaryNode = methodNode.SelectSingleNode("summary");
                if (summaryNode != null)
                {
                    return string.Format("<summaries>{0}</summaries>", methodNode.InnerXml);
                }
            }
    
            return null;
        }
    

    below, you create some useful methods:

        public static string GetSummary(this ApiDescription description, string language)
        {
            string output = string.Empty;
            var summaries = description.Documentation;
            if (!string.IsNullOrEmpty(summaries))
            {
                var xmlDocument = new System.Xml.XmlDocument();
                xmlDocument.LoadXml(summaries);
                var xmlNodeList = xmlDocument.GetElementsByTagName("summary");
                if (xmlNodeList.Count > 0)
                {
                    output = xmlNodeList[0].InnerText;
    
                    for (int i = 0; i < xmlNodeList.Count; i++)
                    {
                        var attribute = xmlNodeList[i].Attributes["xml:lang"];
                        if (attribute!= null && attribute.InnerText == language)
                        {
                            output = xmlNodeList[i].InnerText;
                        }
                    }
                }
            }
    
            return output;
        }
    

    then, you use them in views, for example in \Areas\HelpPage\Views\Help\DisplayTemplates\HelpPageApiModel.cshtml

     <p>@description.GetSummary(@ViewContext.RouteData.Values["language"].ToString())</p>
    

    and finally, to modify the routes:

     context.MapRoute(
                "HelpPage_Default",
                "Help/{language}/{action}/{apiId}",
                new { controller = "Help", language = "en", action = "Index", apiId = UrlParameter.Optional });
    

    links to the help page would be:

    • .../Help/es/Api/GET-api-Values-id
    • .../Help/en/Api/GET-api-Values-id