请选择 进入手机版 | 继续访问电脑版

程序人生

 找回密码
 注册

QQ登录

只需一步,快速开始

程序人生 门户 .NET开发 查看内容

webapi生成帮助文档,减少文档工作量

2016-4-22 17:33| 发布者: sean| 查看: 574| 评论: 0

摘要: 微软的webapi真的很强大,试用webapi时真是太好了,而且Microsoft.AspNet.WebApi.HelpPage安装后,可以直接生成api帮助文档,避免了写一大堆文档的工作量,而且结构相当清晰.使用方法:1.创建好项目后,用Nuget安装包 ...
微软的webapi真的很强大,试用webapi时真是太好了,而且Microsoft.AspNet.WebApi.HelpPage安装后,可以直接生成api帮助文档,避免了写一大堆文档的工作量,而且结构相当清晰.

使用方法:
1.创建好项目后,用Nuget安装包安装Microsoft.Aspnet.WebApi.Helppage,项目结构为

但是默认的的api帮助文档可能不了summary和description,如

显示不了实体的Description

显示不了description,伤心,要知道就是为了用上这个帮助文档,我才直接用实体返回xml格式的

相信一定有解决这个问题的办法,毕竟实体的属性就放在那里,要解决这点,得从程序根源做起,理解程序生成这些描述的方法

看了代码后,发现原来是根据项目的XML文档读取出来的,而我的实体项目和webapi虽然在同一个工程,但是不在同一个项目,因此读取不到xml数据,明白了这点就有办法了

2.在项目的Area/HelpPage新建一个XmlDocumentationProvider.cs类准备来解析xml文档

该文件的代码为

   

/// 

    /// A custom that reads the API documentation from an XML documentation file.

    ///

    public class XmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider

    {

        private XPathNavigator _documentNavigator;

        private const string TypeExpression = "/doc/members/member[@name='T:{0}']";

        private const string MethodExpression = "/doc/members/member[@name='M:{0}']";

        private const string PropertyExpression = "/doc/members/member[@name='P:{0}']";

        private const string FieldExpression = "/doc/members/member[@name='F:{0}']";

        private const string ParameterExpression = "param[@name='{0}']";


        ///

        /// Initializes a new instance of the class.

        ///

        /// The physical path to XML document.

        public XmlDocumentationProvider(string documentPath)

        {

            if (documentPath == null)

            {

                throw new ArgumentNullException("documentPath");

            }

            XPathDocument xpath = new XPathDocument(documentPath);

            _documentNavigator = xpath.CreateNavigator();

        }


        public string GetDocumentation(HttpControllerDescriptor controllerDescriptor)

        {

            XPathNavigator typeNode = GetTypeNode(controllerDescriptor.ControllerType);

            return GetTagValue(typeNode, "summary");

        }


        public virtual string GetDocumentation(HttpActionDescriptor actionDescriptor)

        {

            XPathNavigator methodNode = GetMethodNode(actionDescriptor);

            return GetTagValue(methodNode, "summary");

        }


        public virtual string GetDocumentation(HttpParameterDescriptor parameterDescriptor)

        {

            ReflectedHttpParameterDescriptor reflectedParameterDescriptor = parameterDescriptor as ReflectedHttpParameterDescriptor;

            if (reflectedParameterDescriptor != null)

            {

                XPathNavigator methodNode = GetMethodNode(reflectedParameterDescriptor.ActionDescriptor);

                if (methodNode != null)

                {

                    string parameterName = reflectedParameterDescriptor.ParameterInfo.Name;

                    XPathNavigator parameterNode = methodNode.SelectSingleNode(String.Format(CultureInfo.InvariantCulture, ParameterExpression, parameterName));

                    if (parameterNode != null)

                    {

                        return parameterNode.Value.Trim();

                    }

                }

            }


            return null;

        }


        public string GetResponseDocumentation(HttpActionDescriptor actionDescriptor)

        {

            XPathNavigator methodNode = GetMethodNode(actionDescriptor);

            return GetTagValue(methodNode, "returns");

        }


        public string GetDocumentation(MemberInfo member)

        {

            string memberName = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(member.DeclaringType), member.Name);

            string expression = member.MemberType == MemberTypes.Field ? FieldExpression : PropertyExpression;

            string selectExpression = String.Format(CultureInfo.InvariantCulture, expression, memberName);

            XPathNavigator propertyNode = _documentNavigator.SelectSingleNode(selectExpression);

            return GetTagValue(propertyNode, "summary");

        }


        public string GetDocumentation(Type type)

        {

            XPathNavigator typeNode = GetTypeNode(type);

            return GetTagValue(typeNode, "summary");

        }


        private XPathNavigator GetMethodNode(HttpActionDescriptor actionDescriptor)

        {

            ReflectedHttpActionDescriptor reflectedActionDescriptor = actionDescriptor as ReflectedHttpActionDescriptor;

            if (reflectedActionDescriptor != null)

            {

                string selectExpression = String.Format(CultureInfo.InvariantCulture, MethodExpression, GetMemberName(reflectedActionDescriptor.MethodInfo));

                return _documentNavigator.SelectSingleNode(selectExpression);

            }


            return null;

        }


        private static string GetMemberName(MethodInfo method)

        {

            string name = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", GetTypeName(method.DeclaringType), method.Name);

            ParameterInfo[] parameters = method.GetParameters();

            if (parameters.Length != 0)

            {

                string[] parameterTypeNames = parameters.Select(param => GetTypeName(param.ParameterType)).ToArray();

                name += String.Format(CultureInfo.InvariantCulture, "({0})", String.Join(",", parameterTypeNames));

            }


            return name;

        }


        private static string GetTagValue(XPathNavigator parentNode, string tagName)

        {

            if (parentNode != null)

            {

                XPathNavigator node = parentNode.SelectSingleNode(tagName);

                if (node != null)

                {

                    return node.Value.Trim();

                }

            }


            return null;

        }


        private XPathNavigator GetTypeNode(Type type)

        {

            string controllerTypeName = GetTypeName(type);

            string selectExpression = String.Format(CultureInfo.InvariantCulture, TypeExpression, controllerTypeName);

            return _documentNavigator.SelectSingleNode(selectExpression);

        }


        private static string GetTypeName(Type type)

        {

            string name = type.FullName;

            if (type.IsGenericType)

            {

                // Format the generic type name to something like: Generic{System.Int32,System.String}

                Type genericType = type.GetGenericTypeDefinition();

                Type[] genericArguments = type.GetGenericArguments();

                string genericTypeName = genericType.FullName;


                // Trim the generic parameter counts from the name

                genericTypeName = genericTypeName.Substring(0, genericTypeName.IndexOf('`'));

                string[] argumentTypeNames = genericArguments.Select(t => GetTypeName(t)).ToArray();

                name = String.Format(CultureInfo.InvariantCulture, "{0}{{{1}}}", genericTypeName, String.Join(",", argumentTypeNames));

            }

            if (type.IsNested)

            {

                // Changing the nested type name from OuterType+InnerType to OuterType.InnerType to match the XML documentation syntax.

                name = name.Replace("+", ".");

            }


            return name;

        }

    }

接着替换掉原始 ~/Areas/HelpPage/HelpPageConfig.cs 内的配置。

//config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/Yii.ApiStore.XML"))); config.SetDocumentationProvider(new MultiXmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/Yii.ApiStore.XML"), HttpContext.Current.Server.MapPath("~/App_Data/Yii.ApiEntity.XML")));


为了方便xml文件的读取,还需要使用visual studio的生成事件,预生成事件命令行

具体代码 copy $(SolutionDir)Yii.ApiEntity\bin\Debug\Yii.ApiEntity.XML $(ProjectDir)App_Data\Yii.ApiStore.XML

重新生成项目试试,summary和description来了

如果需要源码的程序朋友,可以入我们程序人生群找群主索取



鲜花

握手

雷人

路过

鸡蛋

相关阅读

最新评论

Web开发技术
Asp.net Mvc5的项目结构
Asp.net Mvc5的项目结构
用Visual studio创建了一个MVC5的项目,其项目结构如下分别对这个MVC的项目模板各个目
我真的不想成为Web前端程序员
我真的不想成为Web前端程序员
职位名称并不代表技能,从事web开发很多年,我现在真的不想成为一个纯粹的web前端程序
MVC5 - Claims-based认证和OWIN(二)
MVC5 - Claims-based认证和OWIN(二)
到底什么是OWIN  首先我们来简单介绍一下OWin,它是由微软ASP.NET小组成员组织成立
MVC5 - Claims-based认证和OWIN(一)
MVC5 - Claims-based认证和OWIN(一)
目录ASP.NET Identity 登录原理什么是Claims-based (基于声明) 的认证ASP.NET 下Claim
想成为一名Web前端开发人员,该学习哪些技术
想成为一名Web前端开发人员,该学习哪些技
Web前端开发者越来越受到追捧,以致于很多后端开发人员都转而去做前端工程师,甚至参
webapi生成帮助文档,减少文档工作量
webapi生成帮助文档,减少文档工作量
微软的webapi真的很强大,试用webapi时真是太好了,而且Microsoft.AspNet.WebApi.Help

关于程序人生网|小黑屋|手机版|Archiver|

程序人生 | QQ

粤公网安备 44040202000007号

( 粤ICP备13038131号-5 )

返回顶部