zoukankan      html  css  js  c++  java
  • WebAPI生成可导入到PostMan的数据

    一、前言

    现在使用WebAPI来作为实现企业服务化的需求非常常见,不可否认它也是很便于使用的,基于注释可以生成对应的帮助文档(Microsoft.AspNet.WebApi.HelpPage),但是比较便利和可持久化的调试官方却没有相应的集成,虽然我们可以使  用诸如Fiddler、Swagger、PostMan、及其他手写代码的方式等等来调试我们的WebAPI,但是却依然不是很方便,对于公司来说也需要有一种可以统一、可持久化、且行之有效的规范。

    调试接口我希望他能达到以下3点:

    1:可根据接口定义生成测试数据。

    2:测试数据可持久化,便于持续迭代。

    3:测试数据可共享。文本主要介绍如何利用PostMan实现这3点。

    二、有哪些调试方法

    目前所知道的调试方式有:

    1:耳熟能详的Fiddler就不说了,功能非常强大,但不是我们想要的。

    2:PostMan,使用方便且满足上面的2和3,这是一个谷歌插件(地址在这),也有App版本(https://www.getpostman.com/)推荐。

    3:Swagger,已有人将其结合SwaggerUI集成到WebAPI中,Nuget上安装

    install-package Swashbuckle

    即可,项目地址https://github.com/domaindrivendev/Swashbuckle

    4:手写HttpClient来实现,其他的还有https://github.com/wuchang/WebApiTestClient

    以上这几种方法比较推荐的自然是PostMan。

    三、PostMan的基本操作

    我们先来看看使用PosMan的一些基本操作。

    如下所示,我们定义了几个简单的方法来作为我们调试的接口。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Http;
    using WebAPI2PostMan.Models;
    
    namespace WebAPI2PostMan.Controllers
    {
        /// <summary>
        ///     产品服务
        /// </summary>
        [RoutePrefix("Product")]
        public class ProductController : ApiController
        {
            private static readonly List<Product> Products = new List<Product>
            {
                new Product{Id = Guid.NewGuid(), Description = "产品描述",Name = "产品名称",Price = 123},
                new Product{Id = Guid.NewGuid(), Description = "产品描述",Name = "产品名称",Price = 124},
                new Product{Id = Guid.NewGuid(), Description = "产品描述",Name = "产品名称",Price = 125},
                new Product{Id = Guid.NewGuid(), Description = "产品描述",Name = "产品名称",Price = 126}
            };
    
            /// <summary>
            ///     获取所有产品
            /// </summary>
            [HttpGet, Route("All")]
            public IEnumerable<Product> Get()
            {
                return Products;
            }
    
            /// <summary>
            ///     获取产品
            /// </summary>
            /// <param name="id">产品编号</param>
            [HttpGet, Route("{id}")]
            public string Get(Guid id)
            {
                return "value";
            }
    
            /// <summary>
            ///     添加产品
            /// </summary>
            /// <param name="request">产品请求</param>
            [HttpPost, Route("")]
            public string Post(Product request)
            {
                Products.Add(request);
                return "ok";
            }
            /// <summary>
            ///     编辑产品
            /// </summary>
            /// <param name="id">产品编号</param>
            /// <param name="request">编辑后的产品</param>
            [HttpPut, Route("{id}")]
            public void Put(int id, Product request)
            {
            }
            /// <summary>
            ///     删除产品
            /// </summary>
            /// <param name="id">产品编号</param>
            [HttpDelete, Route("{id}")]
            public string Delete(Guid id)
            {
                var model = Products.FirstOrDefault(x => x.Id.Equals(id));
                Products.Remove(model);
                var result = string.Format("编号为{0}的产品删除成功!", id);
                return result;
            }
        }
    }
    

    在Nuget里添加了Microsoft.AspNet.WebApi.HelpPage之后生成的帮助文档如下图。

    image

    接下来,我们使用PostMan来调试我们定义的接口。在这里我使用插件版的PostMan作为演示。

    获取所有产品这种其实直接使用浏览器访问就可以达到调试的目的,但是若有特殊Header或身份验证时就不太方便了,如下在PostMan中输入对应地址点击【Send】即可看到返回的数据及消耗的时间和HttpStatus等。

    image

    对于我们常用的我们可以点击Add to collection将其加入到Collections中便于下次测试。

    image

    image

    接下来,我们对新增产品添加调试。

    image

    其余的类似,请求的方法类型与Http请求类型一致。

    image

    四、生成PostMan导入数据

    那么,对于参数较多的接口时第一次添加参数是比较繁琐的,所以我希望能有根据接口定义生成出可以导入到PostMan中的方法,分析Postman下载出来的数据格式可见其实就是一个Json格式的文件。

    image

    image

    那既然是Json格式的文件,我们就可以根据它所需要的格式生成。首先我们定义出需要的类,并没有包含全部的属性,APP版本有一些是否同步等属性并没有加进来,有兴趣的朋友可以研究一下。

    public class PostmanCollection
     {
         public string id { get; set; }
         public string name { get; set; }
         public string description { get; set; }
         public List<string> order { get; set; }
         public long timestamp { get; set; }
         public List<PostmanRequest> requests { get; set; }
     }
    
     public class PostmanRequest
     {
         public string collection { get; set; }
         public string id { get; set; }
         public string name { get; set; }
         public string dataMode { get; set; }
         public List<PostmanData> data { get; set; }
         public string description { get; set; }
         public string descriptionFormat { get; set; }
         public string headers { get; set; }
         public string method { get; set; }
         public Dictionary<string, string> pathVariables { get; set; }
         public string url { get; set; }
         public int version { get; set; }
         public string collectionId { get; set; }
     }
    
     public class PostmanData
     {
         public string key { get; set; }
         public string value { get; set; }
         public string type {
             get { return "text"; }
         }
         public bool enabled {
             get { return true; }
         }
     }

    PostMan支持从地址导入,所以我们可以定义个PostManController要根据接口定义来生成我们的Json数据。

    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Http;
    using System.Web.Http.Description;
    using System.Web.Http.Results;
    using Newtonsoft.Json;
    using WebAPI2PostMan.Areas.HelpPage;
    using WebAPI2PostMan.Models;
    
    namespace WebAPI2PostMan.Controllers
    {
        /// <summary>
        /// 
        /// </summary>
        [RoutePrefix("PostMan")]
        public class PostManController : ApiController
        {
            private const string Host = "http://localhost:11488/";
    
            /// <summary>
            ///     获取PostMan集合
            /// </summary>
            /// <returns></returns>
            [Route("")]
            public JsonResult<PostmanCollection> GetPostmanCollection()
            {
                var collectionId = PostMan.GetId();
                var apis = Configuration.Services.GetApiExplorer().ApiDescriptions.Where(x => x.Documentation != null);
                var requests = GetPostmanRequests(apis, collectionId);
                var collection = new PostmanCollection
                {
                    id = collectionId,
                    name = "WebAPI2PostMan",
                    description = "",
                    order = requests.Select(x => x.id).ToList(),
                    timestamp = 0,
                    requests = requests
                };
    
                return Json(collection);
            }
    
            private List<PostmanRequest> GetPostmanRequests(IEnumerable<ApiDescription> apis, string collectionId)
            {
                return apis.Select(api => new PostmanRequest
                {
                    collection = collectionId,
                    id = PostMan.GetId(),
                    name = api.Documentation,
                    dataMode = "urlencoded",
                    data = GetPostmanDatas(api),
                    description = "",
                    descriptionFormat = "html",
                    headers = "",
                    method = api.HttpMethod.Method,
                    pathVariables = new Dictionary<string, string>(),
                    url = Host + api.RelativePath,
                    version = 2,
                    collectionId = collectionId
                }).ToList();
            }
    
            private List<PostmanData> GetPostmanDatas(ApiDescription api)
            {
                var postmandatas = new List<PostmanData>();
                var apiModel = Configuration.GetHelpPageApiModel(api.GetFriendlyId());
                var raw = apiModel.SampleRequests.Values.FirstOrDefault();
                if (raw == null) return postmandatas;
                var pdata = JsonConvert.DeserializeObject<Dictionary<string,string>>(raw.ToString());
                postmandatas.AddRange(pdata.Select(model => new PostmanData {key = model.Key, value = model.Value}));
                return postmandatas;
            }
        }
    }
    

    主要生成代码就是获取所有接口和接口定义的参数。值得一提的是,我们可以借助Microsoft.AspNet.WebApi.HelpPage来获取SampleRequests,从而使用SampleRequests来填充我们的测试数据。

    运行程序访问http://localhost:11488/PostMan 并将其导入到PostMan。

    image

    image

    效果还是可以接受的,还有写可以拓展的地方,比如可以直接一键导入到PostMan程序中,用谷歌浏览器审查元素可以发现导入的方法是importCollectionFromUrl,在console中输入

    window.open("chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm/index.html");
    pm.collections.importCollectionFromUrl("http://localhost:11488/postman");

    就可以达到一键导入的目的了。但是遗憾的是,必须要在插件内调用才有效,代码匆忙,还有很多地方可以继续拓展,不过本文的目的已经达到了。

    示例代码:https://github.com/yanghongjie/WebAPI2PostMan

  • 相关阅读:
    c语言结构体数组引用
    c语言结构体数组定义的三种方式
    如何为SAP WebIDE开发扩展(Extension),并部署到SAP云平台上
    SAP SRM ABAP Webdynpro和CFCA usb key集成的一个原型开发
    使用SAP API portal进行SAP SuccessFactors的API测试
    SAP UI5应用里的页面路由处理
    在SAP WebIDE Database Explorer里操作hdi实例
    如何使用SAP事务码SAT进行UI应用的性能分析
    使用SAP WebIDE进行SAP Cloud Platform Business Application开发
    SAP CRM WebClient UI ON_NEW_FOCUS的用途
  • 原文地址:https://www.cnblogs.com/idoudou/p/WebApi2PostMan.html
Copyright © 2011-2022 走看看