Using swagger API documentation in MVC projects

Time:2020-6-28

Reference documents:

https://www.cnblogs.com/liaods/p/10101513.html

https://www.cnblogs.com/zyz-Notes/p/12030281.html

 

This example uses MVC project for demonstration (it is not recommended to use webapi directly), and Framework version uses 4.6.2

In order to support webapi, we need to change the current MVC project. Right click the project and add the support of webapi through nuget

 

In app_ Add webapiconfig class under start folder

public class WebApiConfig
     {
         public static void Register(HttpConfiguration config)
         {
             //Web API configuration and services
             //Web API routing
             config.MapHttpAttributeRoutes();
 
             config.Routes.MapHttpRoute(
                 name: "DefaultApi",
                 routeTemplate: "api/{controller}/{action}/{id}",
                 defaults: new { id = RouteParameter.Optional }
             );
             var jsonFormatter = new JsonMediaTypeFormatter();
             //jsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
         }
     }

Then register the change file in the global, put the code in the second line, and then you can use it

Right click project installation: swashbuckle version 5.6.0

 

After successful installation, in app_ There is an additional file in the start folder: SwaggerConfig.cs

 

Open global view_ Layout.cshtml , add a link to it:

  • @Html.ActionLink(“Swagger Help”, “”, “Swagger”, new { area = “” }, null)
  • Direct operation, the effect is as follows:

    Add a test interface, userinfocontroller

    public class UserInfoController : BaseController
         {
             /// 
             ///Get: user information home interface
             /// 
             /// 
             ///I'm the note
             /// 
             ///I'm returning information
             [HttpGet]
             public IHttpActionResult Index()
             {
                 return Json("Hello World");
             }
         }

    As shown in the figure below, the interface is displayed, but it is all in English, and the note information is not displayed. It will be solved later

     

    Click “try it out” to return to the interface content

    Next, we solve the problem of not displaying the notes. Right click the project property and check the XML document file option in the generate tab.

    Then open SwaggerConfig.cs Class, find the function: c.includexmlcomments (getxmlcommentspath()), and release the line of code comment

    And add method: getxmlcommentspath()

    /// 
            ///Get document path
            /// 
            /// 
            static string GetXmlCommentsPath()
            {
                return [email protected]"{System.AppDomain.CurrentDomain.BaseDirectory}\bin\Swagger.Mvc.xml";
            }

    Now the annotation information is displayed, but other places are still in English

    Add Chinese support, add custom Chinese script, right-click project, add folder swagger, add JS script file swagger_ lang.js , right click the script file, and the build operation in the attribute is changed to the embedded resource

     

    Copy the following script:

    ///
    ///Chinese conversion
    ///
    var SwaggerTranslator = (function () {
        //Regularly execute the test to see if it is converted into Chinese, 500 times at most, i.e. 500 * 50 / 1000 = 25s
        var iexcute = 0,
            //Chinese language pack
            _words = {
                "Warning: deprecated": "warning: obsolete",
                "Implementation notes": "implementation notes",
                "Response class": "response class",
                "Status": "status",
                "Parameters": "parameters",
                "Parameter": "parameter",
                "Value": "value",
                "Description": "description",
                "Parameter type": "parameter type",
                "Data type": "data type",
                "Response messages": "response messages",
                "HTTP status code": "HTTP status code",
                "Reason": "reason",
                "Response model": "response model",
                "Request URL": "request URL",
                "Response body": "response body",
                "Response code": "response code",
                "Response headers": "response headers",
                "Hide response": hide response,
                "Heads": "heads",
                "Try it out!": "try it! "
                "Show / hide": "show / hide",
                "List operations": "display operations",
                "Expand operations": "expand operations",
                "Raw": "original",
                "Can't parse JSON. Raw result": "cannot parse JSON. Original result",
                "Model schema": model architecture,
                "Model": "model",
                "Apply": "application",
                "Username": "user name",
                "Password": "password",
                "Terms of service": "terms of service",
                "Created by": "created by",
                "See more at": "see more at":,
                "Contact the developer": "contact the developer",
                "API version": "API version",
                "Response content type": "response content type",
                "Fetching resource": "fetching resources",
                "Fetching resource list": "getting resource list",
                "Explore": "Browse",
                "Show swagger petstore example APIs": "show swagger petstore example APIs",
                "Can't read from server. It may not have the appropriate access control origin settings.": "can't read from server. Access control origin may not be set correctly. "
                "Please specify the protocol for": "please specify the protocol:",
                "Can't read swagger JSON from": "cannot read swagger JSON from",
                "Finished loading resource information. Rendering swagger UI": "loaded resource information. Rendering swagger UI ",
                "Unable to read API": "unable to read API",
                "From path": "from path",
                "Click to set as parameter value": "click to set parameters",
                "Server returned": "server returned"
            },
    
            //Perform the conversion regularly
            _translator2Cn = function () {
                if ($("#resources_container .resource").length > 0) {
                    _tryTranslate();
                }
    
                if ($("#explore").text() == "Explore" && iexcute < 500) {
                    iexcute++;
                    setTimeout(_translator2Cn, 50);
                }
            },
    
            //Set controller notes
            _setControllerSummary = function () {
                $.ajax({
                    type: "get",
                    async: true,
                    url: $("#input_baseUrl").val(),
                    dataType: "json",
                    success: function (data) {
                        var summaryDict = data.ControllerDesc;
                        var id, controllerName, strSummary;
                        $("#resources_container .resource").each(function (i, item) {
                            id = $(item).attr("id");
                            if (id) {
                                controllerName = id.substring(9);
                                strSummary = summaryDict[controllerName];
                                if (strSummary) {
                                    $(item).children(".heading").children(".options").prepend('' + strSummary + '');
                                }
                            }
                        });
                    }
                });
            },
    
            //Try to convert English to Chinese
            _tryTranslate = function () {
                $('[data-sw-translate]').each(function () {
                    $(this).html(_getLangDesc($(this).html()));
                    $(this).val(_getLangDesc($(this).val()));
                    $(this).attr('title', _getLangDesc($(this).attr('title')));
                });
            },
            _getLangDesc = function (word) {
                return _words[$.trim(word)] !== undefined ? _words[$.trim(word)] : word;
            };
    
        return {
            Translator: function () {
                document.title  ="API description document";
                $('body').append('.controller-summary{color:#10a54a !important;word-break:keep-all;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:250px;text-align:right;cursor:default;} ');
                $("logo"). HTML ("interface description"). Attr ("href", "/ home / index");
                //Set controller description
                _setControllerSummary();
                _translator2Cn();
            }
        }
    })();
    //Perform conversion
    SwaggerTranslator.Translator();

    Open SwaggerConfig.cs Class, find the function: injectjavascript, and modify it to the upper customized JS file path. The format is separated by dots

    c.InjectJavaScript(thisAssembly, "Swagger.Mvc.Swagger.swagger_lang.js");

    Add controller description and interface document cache

    public class CachingSwaggerProvider : ISwaggerProvider
         {
             private static ConcurrentDictionary _cache =
                 new ConcurrentDictionary();
     
             private readonly ISwaggerProvider _swaggerProvider;
     
             public CachingSwaggerProvider(ISwaggerProvider swaggerProvider)
             {
                 _swaggerProvider = swaggerProvider;
             }
     
             public SwaggerDocument GetSwagger(string rootUrl, string apiVersion)
             {
                 var cacheKey = string.Format("{0}_{1}", rootUrl, apiVersion);
                 SwaggerDocument srcDoc = null;
                 //Read only once
                 if (!_cache.TryGetValue(cacheKey, out srcDoc))
                 {
                     srcDoc = _swaggerProvider.GetSwagger(rootUrl, apiVersion);
     
                     srcDoc.vendorExtensions = new Dictionary { { "ControllerDesc", GetControllerDesc() } };
                     _cache.TryAdd(cacheKey, srcDoc);
                 }
                 return srcDoc;
             }
     
             /// 
             ///Read controller description from API document
             /// 
             ///Description of all controllers
             public static ConcurrentDictionary GetControllerDesc()
             {
                 string xmlpath = string.Format("{0}/bin/Swagger.Mvc.xml", System.AppDomain.CurrentDomain.BaseDirectory);
                 ConcurrentDictionary controllerDescDict = new ConcurrentDictionary();
                 if (File.Exists(xmlpath))
                 {
                     XmlDocument xmldoc = new XmlDocument();
                     xmldoc.Load(xmlpath);
                     string type = string.Empty, path = string.Empty, controllerName = string.Empty;
     
                     string[] arrPath;
                     int length = -1, cCount = "Controller".Length;
                     XmlNode summaryNode = null;
                     foreach (XmlNode node in xmldoc.SelectNodes("//member"))
                     {
                         type = node.Attributes["name"].Value;
                         if (type.StartsWith("T:"))
                         {
                             //Controller
                             arrPath = type.Split('.');
                             length = arrPath.Length;
                             controllerName = arrPath[length - 1];
                             if (controllerName.EndsWith("Controller"))
                             {
                                 //Get controller comment
                                 summaryNode = node.SelectSingleNode("summary");
                                 string key = controllerName.Remove(controllerName.Length - cCount, cCount);
                                 if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText) && !controllerDescDict.ContainsKey(key))
                                 {
                                     controllerDescDict.TryAdd(key, summaryNode.InnerText.Trim());
                                 }
                             }
                         }
                     }
                 }
                 return controllerDescDict;
             }
     
     
         }

    stay SwaggerConfig.cs Release comment code in class:

    c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider));

    After running the program again, it is now in.

    Line break for remarks, and add after the corresponding remarks
    Can appear line feed, line feed labels to appear in pairs, otherwise error will be reported

    The final operation effect is as follows:

     

    Summary:

    Finally, there is a problem that project names cannot be separated by points, such as: Swagger.Mvc This is not good. For such a name, the path will not be found when it is translated into Chinese. So we need to remove the middle point, the pit!