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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM