一、前言

现在使用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之后生成的帮助文档如下图。

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

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

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

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

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

四、生成PostMan导入数据

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

那既然是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。

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

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

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

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

WebAPI生成可导入到PostMan的数据的更多相关文章

  1. 自由导入你的增量数据-根据条件将sqlserver表批量生成INSERT语句的存储过程实施笔记

    文章标题: 自由导入你的增量数据-根据条件将sqlserver表批量生成INSERT语句的存储过程增强版 关键字 : mssql-scripter,SQL Server 文章分类: 技术分享 创建时间 ...

  2. 批量生成sqlldr文件,高速卸载数据

    SQL*Loader 是用于将外部数据进行批量高速加载的数据库的最高效工具,可用于将多种平面格式文件加载到Oracle数据库.SQL*Loader支持传统路径模式以及直接路径这两种加载模式.关于SQL ...

  3. NodeJs之EXCEL文件导入导出MongoDB数据库数据

    NodeJs之EXCEL文件导入导出MongoDB数据库数据 一,介绍与需求 1.1,介绍 (1),node-xlsx : 基于Node.js解析excel文件数据及生成excel文件. (2),ex ...

  4. 通过生成HFile导入HBase

    要实现DataFrame通过HFile导入HBase有两个关键步骤 第一个是要生成Hfile第二个是HFile导入HBase 测试DataFrame数据来自mysql,如果对读取mysql作为Data ...

  5. 导入CSV格式的数据

    导入CSV格式的数据 (参见http://dev.mysql.com/doc/refman/5.6/en/load-data.html) 1.数据库表(st_pptn_r) CREATE TABLE ...

  6. linux下导入、导出mysql数据库命令 下载文件到本地

    一.下载到本地 yum install lrzsz sz filename  下载 rz filename  上传   linux下导入.导出mysql数据库命令 一.导出数据库用mysqldump命 ...

  7. 游标、获取本地本地多个文件、Excel数据导入、跨服务器数据拷贝、行转列示例

    )='C:\Users\Administrator\Desktop\待处理数据\顺江学校4\' ---------------------------------------------------- ...

  8. Oracle生成查询包括对应于所有数据表记录语句中指定的字段名

    应用:已知的字段名,表中的所有数据的查询数据库中包含的所有数据表的字段名 操作方法:指定字段名,用户数据库表,它可以执行以下查询 --Oracle生成查询包括对应于所有数据表记录语句中指定的字段名 d ...

  9. SQL C# nvarchar类型转换为int类型 多表查询的问题,查询结果到新表,TXT数据读取到控件和数据库,生成在控件中的数据如何存到TXT文件中

    在数据库时候我设计了学生的分数为nvarchar(50),是为了在从TXT文件中读取数据插入到数据库表时候方便,但是在后期由于涉及到统计问题,比如求平均值等,需要int类型才可以,方法是:Conver ...

随机推荐

  1. How To Use Goto?

    看到,网上很多人对于goto的询问, 因为本身在工作中经常使用到,所以写下此文, 如有错误, 请指出. 本人写博文的时候主要从事C++工作 对于goto的态度,本人目前成长如下: 学生时代 老师课堂上 ...

  2. 学习RBAC 用户·角色·权限·表

  3. 2013 duilib入门简明教程 -- 前言(1)

        关于duilib的介绍就不多讲了,一来不熟,二来小伙伴们想必已经对比了多个界面库,也无需赘述.下面进入正题:     不看广告看疗效! 已有众多知名公司采用duilib做为界面库,如华为网盘. ...

  4. UpdateException-更新条目时出错分析

    不屁话1张图搞定: 我是这个错: 2015-03-27 00:25:00,493 [9] ERROR log - System.Data.Entity.Infrastructure.DbUpdateE ...

  5. 前端学PHP之数组函数

    × 目录 [1]键值操作 [2]记数[3]回调函数[4]组合[5]栈和队列[6]顺序 前面的话 PHP中的数组功能非常强大,数组处理函数有着强大.灵活.高效的特点.PHP5提供了近100个操作数组的系 ...

  6. 控制对话框风格的activity的显示大小与位置

    项目开发的需要,因为到现在项目接近完工,用户提出对条件筛选方式进行修改,为做到最小的改动实现用户的需求,各种百度,对于对话框风格大家普遍使用PopupWindow,但由于之前开发设计时使用的是acti ...

  7. 应用程序框架实战十六:DDD分层架构之值对象(介绍篇)

    前面介绍了DDD分层架构的实体,并完成了实体层超类型的开发,同时提供了验证方面的支持.本篇将介绍另一个重要的构造块——值对象,它是聚合中的主要成分. 如果说你已经在使用DDD分层架构,但你却从来没有使 ...

  8. Util应用程序框架公共操作类(三):数据类型转换公共操作类(扩展篇)

    上一篇以TDD方式介绍了数据类型转换公共操作类的开发,并提供了单元测试和实现代码,本文将演示通过扩展方法来增强公共操作类,以便调用时更加简化. 下面以字符串转换为List<Guid>为例进 ...

  9. 如何搭建NTP服务

    最近,在搭建Oracle RAC过程中,需要用到DNS和NTP,其中,DNS用于域名.IP管理,NTP用于时间同步.其实,很久以前搭建过这两种服务,但技术,本质上,符合“用进废退”的客观规律.用得越频 ...

  10. css:图标与文字对齐的两种方法

    (好久没写博客了,这几个月的积累比较零碎,记在本子上,现在开始整理归类) 在平时写页面的过程中,常遇到要把小图标与文字对齐的情况.比如: 总结了两种方法,代码量都比较少. 第一种 对img设置竖直方向 ...