自定义WebAPI接口帮助文档

自定义WebAPI接口帮助文档

环境:VS2013

搭建项目框架如下:

自定义WebAPI接口帮助文档_第1张图片

Web为WebAPI接口层,Model层用于存放接口的输入输出参数

在网上参考了很多文档,把help page改造方法整理如下:

1.使用nuget安装的最新的help page

vs2013在创建webAPI项目时是默认安装了help page的,不过生成的帮助文档不符合我们需要,可以卸载掉然后安装2.2版本的

自定义WebAPI接口帮助文档_第2张图片

搜索help page,找到安装即可

自定义WebAPI接口帮助文档_第3张图片

2.添加多文件支持类

在WebAPI项目Areas/HelpPage下添加类文件MultiXmlDocumentationProvider.cs

自定义WebAPI接口帮助文档_第4张图片

类内容如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Http.Controllers;
using System.Web.Http.Description;

namespace PP.JiJin.Web.Areas.HelpPage
{
    /// 
    /// A custom  that reads the API documentation from a collection of XML documentation files. 
    /// 
    public class MultiXmlDocumentationProvider : IDocumentationProvider, IModelDocumentationProvider
    {
        /********* 
        ** Properties 
        *********/
        /// The internal documentation providers for specific files.  
        private readonly XmlDocumentationProvider[] Providers;


        /********* 
        ** Public methods 
        *********/
        /// Construct an instance.  
        /// The physical paths to the XML documents.  
        public MultiXmlDocumentationProvider(params string[] paths)
        {
            this.Providers = paths.Select(p => new XmlDocumentationProvider(p)).ToArray();
        }

        /// Gets the documentation for a subject.  
        /// The subject to document.  
        public string GetDocumentation(MemberInfo subject)
        {
            return this.GetFirstMatch(p => p.GetDocumentation(subject));
        }

        /// Gets the documentation for a subject.  
        /// The subject to document.  
        public string GetDocumentation(Type subject)
        {
            return this.GetFirstMatch(p => p.GetDocumentation(subject));
        }

        /// Gets the documentation for a subject.  
        /// The subject to document.  
        public string GetDocumentation(HttpControllerDescriptor subject)
        {
            return this.GetFirstMatch(p => p.GetDocumentation(subject));
        }

        /// Gets the documentation for a subject.  
        /// The subject to document.  
        public string GetDocumentation(HttpActionDescriptor subject)
        {
            return this.GetFirstMatch(p => p.GetDocumentation(subject));
        }

        /// Gets the documentation for a subject.  
        /// The subject to document.  
        public string GetDocumentation(HttpParameterDescriptor subject)
        {
            return this.GetFirstMatch(p => p.GetDocumentation(subject));
        }

        /// Gets the documentation for a subject.  
        /// The subject to document.  
        public string GetResponseDocumentation(HttpActionDescriptor subject)
        {
            return this.GetFirstMatch(p => p.GetDocumentation(subject));
        }


        /********* 
        ** Private methods 
        *********/
        /// Get the first valid result from the collection of XML documentation providers.  
        /// The method to invoke.  
        private string GetFirstMatch(Func expr)
        {
            return this.Providers
                .Select(expr)
                .FirstOrDefault(p => !String.IsNullOrWhiteSpace(p));
        }
    } 
}

点击类中报错的地方,根据VS智能提示添加对应引用即可

3.修改项目生成输出XML文件

本例中,接口引用的输入输出参数类在另外一个子项目PP.TradeCenter.Model中,因此,右键PP.TradeCenter.Model子项目→属性

自定义WebAPI接口帮助文档_第5张图片

勾选“XML文档文件”,填写生成的xml文件路径,本例指定为App_Data\XmlDocument.xml

同理,对WebAPI项目做同样的修改

自定义WebAPI接口帮助文档_第6张图片

然后在WebAPI项目属性的生成事件中添加命令:

copy "$(SolutionDir)PP.TradeCenter.Model\App_Data\XmlDocument.xml" "$(ProjectDir)\App_Data\PP.TradeCenter.Model.XmlDocument.xml"

自定义WebAPI接口帮助文档_第7张图片

这条命令的含义是在项目生成时,将PP.TradeCenter.Model子项目中App_Data文件夹下XmlDocument.xml文件复制到当前子项目(即PP.TradeCenter.Web)的App_Data文件夹下,并重命名为PP.TradeCenter.Model.XmlDocument.xml

使用时将PP.TradeCenter.Model改成自己Model项目名称即可,PP.TradeCenter.Model.XmlDocument.xml这个文件名也可以根据自己需要命名,下一步注册时候需要使用

4.修改WebAPI项目下HelpPage的配置文件

自定义WebAPI接口帮助文档_第8张图片

增加一行代码:

config.SetDocumentationProvider(new MultiXmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/XmlDocument.xml"), HttpContext.Current.Server.MapPath("~/App_Data/PP.TradeCenter.Model.XmlDocument.xml")));

自定义WebAPI接口帮助文档_第9张图片

这行代码里的两个xml文件名字需要和上一步子项目生成属性中配置的一致。

5.修改WebAPI的默认路由

自定义WebAPI接口帮助文档_第10张图片自定义WebAPI接口帮助文档_第11张图片

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

VS2013创建的WebAPI项目默认的路由是没有action的,这个有点小坑

到这里已经配置完成了,生成项目即可

新建一个API控制器

自定义WebAPI接口帮助文档_第12张图片自定义WebAPI接口帮助文档_第13张图片自定义WebAPI接口帮助文档_第14张图片

自定义WebAPI接口帮助文档_第15张图片

最终生成的help文档如下:

自定义WebAPI接口帮助文档_第16张图片

自定义WebAPI接口帮助文档_第17张图片

6.输入参数验证

对接口的输入参数进行验证可以保证接口的安全

右键Model项目,添加引用

自定义WebAPI接口帮助文档_第18张图片

自定义WebAPI接口帮助文档_第19张图片

勾选对System.ComponentModel.DataAnnotations的引用,确认

然后我们右键这个添加的引用,选择“在对象浏览器中查看”

自定义WebAPI接口帮助文档_第20张图片

可以看到很多验证供选择:常用的有Require必填,Range验证数字范围,StringLength验证字符串长度,MaxLength最大长度、MinLength最小长度,Phone验证手机号,Email验证邮件地址,复杂的可以使用RegularExpression正则表达式验证

自定义WebAPI接口帮助文档_第21张图片

使用也比较方便,在输入参数对应属性上加上验证特性即可,示例如下:

自定义WebAPI接口帮助文档_第22张图片

验证添加完以后还不会生效,我们还需要把这些验证进行注册,微软官网示例的用法是在调用的类上加上

[MetadataType(typeof(input类名))]

webapi的用法参考:https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api

这里对输入参数验证进行一些整合

(1)在Model中Output中添加InputParamInvalidInfoOutput类、Result类、BusinessState类

自定义WebAPI接口帮助文档_第23张图片

InputParamInvalidInfoOutput类内容如下:

    /// 
    /// Web Api输入参数异常信息
    /// 
    public class InputParamInvalidInfoOutput
    {
        /// 
        /// 输入参数
        /// 
        public string Key { set; get; }

        /// 
        /// 错误列表
        /// 
        public List Errors { set; get; }
    }

Result类,用于封装API接口返回结果内容如下:

    /// 
    /// 返回结果
    /// 
    public class Result
    {
        private int code = BusinessState.RESULT_UnLogin.Code;
        object body = new { };
        /// 
        /// 业务码
        /// 
        public int Code
        {
            get { return code; }
            set { code = value; }
        }
        /// 
        /// 业务信息
        /// 
        public string Msg { get; set; }
        /// 
        /// 数据实体
        /// 
        public object Body
        {
            get { return body; }
            set { body = value; }
        }
    }

    /// 
    /// 返回结果
    /// 
    /// 数据实体类型
    public class Result
    {
        private int code = BusinessState.RESULT_UnLogin.Code;
        /// 
        /// 业务码
        /// 
        public int Code
        {
            get { return code; }
            set { code = value; }
        }
        /// 
        /// 业务信息
        /// 
        public string Msg { get; set; }

        T body = default(T);
        /// 
        /// 数据实体
        /// 
        public T Body
        {
            get { return body; }
            set { body = value; }

        }
    }

BusinessState类,用于定义Result类的Code属性编码

    /// 
    /// 业务编码和提示信息
    /// 
    public class CodeMsg
    {
        public CodeMsg(int code, string msg)
        {
            Code = code;
            Msg = msg;
        }
        /// 
        /// 业务码
        /// 
        public int Code { get; set; }
        /// 
        /// 业务消息
        /// 
        public string Msg { get; set; }
    }
    public class BusinessState
    {
        /// 
        /// 成功结果
        /// 
        public static CodeMsg SUCC = new CodeMsg(0, "成功");

        /// 
        /// token过期
        /// 
        public static CodeMsg RESULT_TOKEN_TIMEOUT = new CodeMsg(1, "请重新登录");//token过期
        public static CodeMsg RESULT_UnLogin = new CodeMsg(2, "未登录");
        public static CodeMsg RESULT_TOKEN_LOST = new CodeMsg(3, "请重新登录");//token失效
        public static CodeMsg RESULT_EXCEPTION = new CodeMsg(4, "系统异常,稍后重试");
        public static CodeMsg PARAM_INPUT_MODEL_INVALID = new CodeMsg(5, "查询参数无效,");
    }

(2)在webAPI子项目下新建Filter文件夹,添加类ValidateModelAttribute

自定义WebAPI接口帮助文档_第24张图片

ValidateModelAttribute类内容如下:

    public class ValidateModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.ModelState.IsValid == false)
            {
                //获取model验证失败字段
                List errorList = new List();
                foreach(var key in actionContext.ModelState.Keys){
                    InputParamInvalidInfoOutput errorItem = new InputParamInvalidInfoOutput() { Key = string.Empty, Errors = new List() };
                    errorItem.Key = key;
                    foreach (var error in actionContext.ModelState[key].Errors)
                    {
                        errorItem.Errors.Add(error.ErrorMessage);
                    }
                    errorList.Add(errorItem);
                }
                ErrorObj errObj = new ErrorObj() { ErrorList = errorList };
                var result = new Result()
                    {
                        Code = BusinessState.PARAM_INPUT_MODEL_INVALID.Code,
                        Msg = BusinessState.PARAM_INPUT_MODEL_INVALID.Msg
,
                        Body = errObj
                    };

                //PP.JiJin.BLL.LogBLL.Error("errObj=" + JsonHelper.Serializer(result));

                //组装Response
                HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);

                response.Content = new ObjectContent>(result, new JsonMediaTypeFormatter());
                response.RequestMessage = actionContext.Request;

                //赋值Response
                actionContext.Response = response;
            }
        }

        public class ErrorObj
        {
            public List ErrorList { set; get; }
        }
(3)在WebAPI项目的路由配置文件中注册Model的验证逻辑

自定义WebAPI接口帮助文档_第25张图片

自定义WebAPI接口帮助文档_第26张图片

            //注册Model验证逻辑
            config.Filters.Add(new ValidateModelAttribute());

到此大功告成,使用谷歌浏览器插件postman测试下接口:

自定义WebAPI接口帮助文档_第27张图片

你可能感兴趣的:(ASP.NET,C#)