Postman是一种可用于轻松测试宁静Web服务的工具.
如果Asp.Net项目将WebApi与WebApi Helppages结合使用,则可以为暴露的restful Web服务自动生成文档.
这个自动生成的文档很好,但可以通过增加的可访问性使其更好.
如何组合这些技术技术来生成可以在Postman中导入的JSON文件?
扩展博客文章" 使用ApiExplorer将API信息导出到PostMan,一个用于测试Web API的Chrome扩展 ",可以生成一个可以导入Postman的JSON文件,用于测试和记录.
首先,您需要设置一个可以导出JSON的控制器
////// Based on /// http://blogs.msdn.com/b/yaohuang1/archive/2012/06/15/using-apiexplorer-to-export-api-information-to-postman-a-chrome-extension-for-testing-web-apis.aspx /// [RoutePrefix("api/postman")] public class PostmanApiController : ApiController { ////// Produce [POSTMAN](http://www.getpostman.com) related responses /// public PostmanApiController() { // exists for documentation purposes } private readonly Regex _pathVariableRegEx = new Regex("\\{([A-Za-z0-9-_]+)\\}", RegexOptions.ECMAScript | RegexOptions.Compiled); private readonly Regex _urlParameterVariableRegEx = new Regex("=\\{([A-Za-z0-9-_]+)\\}", RegexOptions.ECMAScript | RegexOptions.Compiled); ////// Get a postman collection of all visible Api /// (Get the [POSTMAN](http://www.getpostman.com) chrome extension) /// ///object describing a POSTMAN collection ///Get a postman collection of all visible api [HttpGet] [Route(Name = "GetPostmanCollection")] [ResponseType(typeof (PostmanCollectionGet))] public IHttpActionResult GetPostmanCollection() { return Ok(this.PostmanCollectionForController()); } private PostmanCollectionGet PostmanCollectionForController() { var requestUri = Request.RequestUri; var baseUri = requestUri.Scheme + "://" + requestUri.Host + ":" + requestUri.Port + HttpContext.Current.Request.ApplicationPath; var postManCollection = new PostmanCollectionGet { Id = Guid.NewGuid(), Name = "[Name of your API]", Timestamp = DateTime.Now.Ticks, Requests = new Collection(), Folders = new Collection (), Synced = false, Description = "[Description of your API]" }; var helpPageSampleGenerator = Configuration.GetHelpPageSampleGenerator(); var apiExplorer = Configuration.Services.GetApiExplorer(); var apiDescriptionsByController = apiExplorer.ApiDescriptions.GroupBy( description => description.ActionDescriptor.ActionBinding.ActionDescriptor.ControllerDescriptor.ControllerType); foreach (var apiDescriptionsByControllerGroup in apiDescriptionsByController) { var controllerName = apiDescriptionsByControllerGroup.Key.Name.Replace("Controller", string.Empty); var postManFolder = new PostmanFolderGet { Id = Guid.NewGuid(), CollectionId = postManCollection.Id, Name = controllerName, Description = string.Format("Api Methods for {0}", controllerName), CollectionName = "api", Order = new Collection () }; foreach (var apiDescription in apiDescriptionsByControllerGroup .OrderBy(description => description.HttpMethod, new HttpMethodComparator()) .ThenBy(description => description.RelativePath) .ThenBy(description => description.Documentation.ToString(CultureInfo.InvariantCulture))) { TextSample sampleData = null; var sampleDictionary = helpPageSampleGenerator.GetSample(apiDescription, SampleDirection.Request); MediaTypeHeaderValue mediaTypeHeader; if (MediaTypeHeaderValue.TryParse("application/json", out mediaTypeHeader) && sampleDictionary.ContainsKey(mediaTypeHeader)) { sampleData = sampleDictionary[mediaTypeHeader] as TextSample; } // scrub curly braces from url parameter values var cleanedUrlParameterUrl = this._urlParameterVariableRegEx.Replace(apiDescription.RelativePath, "=$1-value"); // get pat variables from url var pathVariables = this._pathVariableRegEx.Matches(cleanedUrlParameterUrl) .Cast () .Select(m => m.Value) .Select(s => s.Substring(1, s.Length - 2)) .ToDictionary(s => s, s => string.Format("{0}-value", s)); // change format of parameters within string to be colon prefixed rather than curly brace wrapped var postmanReadyUrl = this._pathVariableRegEx.Replace(cleanedUrlParameterUrl, ":$1"); // prefix url with base uri var url = baseUri.TrimEnd('/') + "/" + postmanReadyUrl; var request = new PostmanRequestGet { CollectionId = postManCollection.Id, Id = Guid.NewGuid(), Name = apiDescription.RelativePath, Description = apiDescription.Documentation, Url = url, Method = apiDescription.HttpMethod.Method, Headers = "Content-Type: application/json", Data = sampleData == null ? null : sampleData.Text, DataMode = "raw", Time = postManCollection.Timestamp, Synced = false, DescriptionFormat = "markdown", Version = "beta", Responses = new Collection (), PathVariables = pathVariables }; postManFolder.Order.Add(request.Id); // add to the folder postManCollection.Requests.Add(request); } postManCollection.Folders.Add(postManFolder); } return postManCollection; } } /// /// Quick comparer for ordering http methods for display /// internal class HttpMethodComparator : IComparer{ private readonly string[] _order = { "GET", "POST", "PUT", "DELETE" }; public int Compare(HttpMethod x, HttpMethod y) { return Array.IndexOf(this._order, x.ToString()).CompareTo(Array.IndexOf(this._order, y.ToString())); } }
并生成适当的模型:
一个用于PostManCollection
////// [Postman](http://getpostman.com) collection representation /// public class PostmanCollectionGet { ////// Id of collection /// [JsonProperty(PropertyName = "id")] public Guid Id { get; set; } ////// Name of collection /// [JsonProperty(PropertyName = "name")] public string Name { get; set; } ////// Collection generation time /// [JsonProperty(PropertyName = "timestamp")] public long Timestamp { get; set; } ////// Requests associated with the collection /// [JsonProperty(PropertyName = "requests")] public ICollectionRequests { get; set; } /// /// **unused always false** /// [JsonProperty(PropertyName = "synced")] public bool Synced { get; set; } ////// folders within the collection /// [JsonProperty(PropertyName = "folders")] public ICollectionFolders { get; set; } /// /// Description of collection /// [JsonProperty(PropertyName = "description")] public string Description { get; set; } }
一个用于PostmanFolder
////// Object that describes a [Postman](http://getpostman.com) folder /// public class PostmanFolderGet { ////// id of the folder /// [JsonProperty(PropertyName = "id")] public Guid Id { get; set; } ////// folder name /// [JsonProperty(PropertyName = "name")] public string Name { get; set; } ////// folder description /// [JsonProperty(PropertyName = "description")] public string Description { get; set; } ////// ordered list of ids of items in folder /// [JsonProperty(PropertyName = "order")] public ICollectionOrder { get; set; } /// /// Name of the collection /// [JsonProperty(PropertyName = "collection_name")] public string CollectionName { get; set; } ////// id of the collection /// [JsonProperty(PropertyName = "collection_id")] public Guid CollectionId { get; set; } }
最后是PostmanRequest的模型
////// [Postman](http://getpostman.com) request object /// public class PostmanRequestGet { ////// id of request /// [JsonProperty(PropertyName = "id")] public Guid Id { get; set; } ////// headers associated with the request /// [JsonProperty(PropertyName = "headers")] public string Headers { get; set; } ////// url of the request /// [JsonProperty(PropertyName = "url")] public string Url { get; set; } ////// path variables of the request /// [JsonProperty(PropertyName = "pathVariables")] public DictionaryPathVariables { get; set; } /// /// method of request /// [JsonProperty(PropertyName = "method")] public string Method { get; set; } ////// data to be sent with the request /// [JsonProperty(PropertyName = "data")] public string Data { get; set; } ////// data mode of reqeust /// [JsonProperty(PropertyName = "dataMode")] public string DataMode { get; set; } ////// name of request /// [JsonProperty(PropertyName = "name")] public string Name { get; set; } ////// request description /// [JsonProperty(PropertyName = "description")] public string Description { get; set; } ////// format of description /// [JsonProperty(PropertyName = "descriptionFormat")] public string DescriptionFormat { get; set; } ////// time that this request object was generated /// [JsonProperty(PropertyName = "time")] public long Time { get; set; } ////// version of the request object /// [JsonProperty(PropertyName = "version")] public string Version { get; set; } ////// request response /// [JsonProperty(PropertyName = "responses")] public ICollectionResponses { get; set; } /// /// the id of the collection that the request object belongs to /// [JsonProperty(PropertyName = "collection-id")] public Guid CollectionId { get; set; } ////// Synching /// [JsonProperty(PropertyName = "synced")] public bool Synced { get; set; } }
现在您需要做的就是向[application] api/postman发出GET请求,并且您将以邮递员可读的形式获得最新的RESTful API.