/// <summary>Writes the parameters.</summary> /// <param name="apiDescription">The API description.</param> public void WriteParameters(ApiDescription apiDescription) { Condition.Requires(apiDescription).IsNotNull(); if (apiDescription.ParameterDescriptions.Any()) { Writer.WriteLine("**Parameters** "); } foreach (var pd in apiDescription.ParameterDescriptions) { if (pd.ParameterDescriptor != null) { Writer.Write("`{0}` {1} - ", pd.ParameterDescriptor.ParameterType.GetFriendlyTypeName(), pd.Name); if (!string.IsNullOrEmpty(pd.Documentation)) { Writer.Write("_{0}_, ", pd.Documentation); } if (pd.ParameterDescriptor.DefaultValue != null) { Writer.Write("default [{0}], ", pd.ParameterDescriptor.DefaultValue); } Writer.WriteLine("{0} ", pd.ParameterDescriptor.IsOptional ? "optional" : "required"); } }; }
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { if (operation.parameters == null) return; HandleFromUriArrayParams(operation); HandleFromUriObjectParams(operation, schemaRegistry, apiDescription); }
public ApiResource(ApiDescription description) { this.Url = this.EnsureStartingSlash(description.RelativePath); this.HttpMethod = description.HttpMethod.Method.ToLower(); this.Name = this.EnsureLowerFirstLetter(description.ActionDescriptor.ActionName); this.ParamsFromQueryString = this.GetParamsFromQueryString(description.ActionDescriptor.GetParameters()); }
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { List<SwaggerDefaultValue> listDefine = new List<SwaggerDefaultValue> { new SwaggerDefaultValue("Compare", "<", "<,<=,>,>=,="), //new SwaggerDefaultValue("Model_URI", "@{body(\'besconnector').Results.output2.FullURL}"), //new SwaggerDefaultValue("Evaluate_Output_Path", "@{body(\'besconnector\').Results.output1.FullURL}") }; if (operation.parameters == null) return; foreach (var param in operation.parameters) { var actionParam = apiDescription.ActionDescriptor.GetParameters().First(p => p.ParameterName == param.name); foreach (SwaggerDefaultValue customAttribute in listDefine) { if (customAttribute.ParameterName == param.name) { param.@default = customAttribute.DefaultValue; string[] listValue = customAttribute.Values.Split(','); if (listValue != null && listValue.Length > 1) param.@enum = listValue; } } } }
private Operation CreateOperation(ApiDescription apiDescription, SchemaRegistry schemaRegistry) { var parameters = apiDescription.ParameterDescriptions .Select(paramDesc => { var inPath = apiDescription.RelativePathSansQueryString().Contains("{" + paramDesc.Name + "}"); return CreateParameter(paramDesc, inPath, schemaRegistry); }) .ToList(); var responses = new Dictionary<string, Response>(); var responseType = apiDescription.ResponseType(); if (responseType == null || responseType == typeof(void)) responses.Add("204", new Response { description = "No Content" }); else responses.Add("200", new Response { description = "OK", schema = schemaRegistry.GetOrRegister(responseType) }); var operation = new Operation { tags = new [] { _options.GroupingKeySelector(apiDescription) }, operationId = apiDescription.FriendlyId(), produces = apiDescription.Produces().ToList(), consumes = apiDescription.Consumes().ToList(), parameters = parameters.Any() ? parameters : null, // parameters can be null but not empty responses = responses, deprecated = apiDescription.IsObsolete() }; foreach (var filter in _options.OperationFilters) { filter.Apply(operation, schemaRegistry, apiDescription); } return operation; }
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { if (operation == null) { throw new ArgumentNullException("operation"); } if (apiDescription == null) { throw new ArgumentNullException("apiDescription"); } Collection<IFilter> filters = apiDescription.ActionDescriptor.ControllerDescriptor.GetFilters(); IEnumerable<IFilter> mobileAppFilter = filters.Where(f => typeof(MobileAppControllerAttribute).IsAssignableFrom(f.GetType())); if (mobileAppFilter.Any()) { if (operation.parameters == null) { operation.parameters = new List<Parameter>(); } operation.parameters.Add(new Parameter { name = "ZUMO-API-VERSION", @in = "header", type = "string", required = true, @default = "2.0.0" }); } }
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { if (operation.operationId == "FileDownload_GetFile") { operation.produces = new[] { "application/octet-stream" }; } }
public static HelpPageApiModel GenerateApiModel(ApiDescription apiDescription, HelpPageSampleGenerator sampleGenerator) { HelpPageApiModel apiModel = new HelpPageApiModel(); apiModel.ApiDescription = apiDescription; try { foreach (var item in sampleGenerator.GetSampleRequests(apiDescription)) { apiModel.SampleRequests.Add(item.Key, item.Value); LogInvalidSampleAsError(apiModel, item.Value); } foreach (var item in sampleGenerator.GetSampleResponses(apiDescription)) { apiModel.SampleResponses.Add(item.Key, item.Value); LogInvalidSampleAsError(apiModel, item.Value); } } catch (Exception e) { apiModel.ErrorMessages.Add(String.Format(CultureInfo.CurrentCulture, "An exception has occurred while generating the sample. Exception Message: {0}", e.Message)); } return apiModel; }
public static MetadataPlainObjects.Fields Generate(MappingRule mappingRule, ApiDescription apiDescription, object originalObject) { var fromBodyParameterType = (from param in mappingRule.MethodExpression.Method.GetParameters() let fromBodyAttr = param.GetCustomAttribute<FromBodyAttribute>() where fromBodyAttr != null select param.ParameterType).FirstOrDefault(); if (fromBodyParameterType == null) return GenerateFromGet(mappingRule, apiDescription, originalObject); var result = new MetadataPlainObjects.Fields(); result.AddRange(from property in fromBodyParameterType.GetProperties() let fieldName = GetFieldName(property) let propVal = property.GetValue(originalObject) let jsonIgnore = property.GetCustomAttribute<JsonIgnoreAttribute>() where jsonIgnore == null select new MetadataPlainObjects.Field { FieldName = fieldName, FieldType = GetFieldType(property), FieldValue = propVal == null ? null : propVal.ToString() }); return result; }
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { if (!operation.responses.ContainsKey("default") && operation.responses.ContainsKey("200")) { operation.responses.Add("default", operation.responses["200"]); } }
private static bool VersionSupportByAttribute(ApiDescription apiDesc, string version) { var attr = apiDesc.ActionDescriptor.GetCustomAttributes<SupportedInVersionsAttribute>().FirstOrDefault(); if (attr == null) return false; return attr.Versions.Contains(version); }
public ApiDescription(System.Web.Http.Description.ApiDescription desc, XmlDocumentationProvider xmlDocProvider) : this() { this.Name = desc.ActionDescriptor.ActionName; this.RelativePath = desc.RelativePath; this.HttpMethod = desc.HttpMethod.Method; this.Controller = desc.ActionDescriptor.ControllerDescriptor.ControllerName; this.Documentation = xmlDocProvider.GetDocumentation(desc.ActionDescriptor); this.ReturnType = xmlDocProvider.GetResponseDocumentation(desc.ActionDescriptor); string permissionCref = null; this.PermissionDescription = xmlDocProvider.GetPermissionDocumentation(desc.ActionDescriptor, out permissionCref); this.PermissionCref = permissionCref; foreach (var paramDesc in desc.ParameterDescriptions) { if (paramDesc.Source == ApiParameterSource.FromBody) { this.BodyType = paramDesc.ParameterDescriptor.ParameterType.ToString(); } else { this.Parameters.Add(new ApiParameter(paramDesc, xmlDocProvider)); } } }
public void HeaderFilter_AddsHeaderRequirement(Collection<IFilter> filters) { // Arrange var swashbuckleFilter = new MobileAppHeaderFilter(); var operation = new Operation(); var controllerDescMock = new Mock<HttpControllerDescriptor>(); controllerDescMock.Setup(c => c.GetFilters()).Returns(filters); var description = new ApiDescription(); description.ActionDescriptor = new ReflectedHttpActionDescriptor(); description.ActionDescriptor.ControllerDescriptor = controllerDescMock.Object; // Act swashbuckleFilter.Apply(operation, null, description); // Assert Assert.NotNull(operation.parameters); Assert.Equal(1, operation.parameters.Count); Parameter parameter = operation.parameters[0]; Assert.Equal("ZUMO-API-VERSION", parameter.name); Assert.Equal("header", parameter.@in); Assert.Equal("string", parameter.type); Assert.Equal("2.0.0", parameter.@default); Assert.True(parameter.required); }
public void Apply( ApiDescription apiDescription, OperationSpec operationSpec, ModelSpecRegistrar modelSpecRegistrar, ModelSpecGenerator modelSpecGenerator) { var responseTypeAttr = apiDescription.ActionDescriptor.GetCustomAttributes<ResponseTypeAttribute>().FirstOrDefault(); if (responseTypeAttr == null) return; IEnumerable<ModelSpec> complexSpecs; var modelSpec = modelSpecGenerator.TypeToModelSpec(responseTypeAttr.Type, out complexSpecs); if (modelSpec.Type == "object") { operationSpec.Type = modelSpec.Id; } else { operationSpec.Type = modelSpec.Type; operationSpec.Format = modelSpec.Format; operationSpec.Items = modelSpec.Items; operationSpec.Enum = modelSpec.Enum; } modelSpecRegistrar.RegisterMany(complexSpecs); }
public void Apply(Operation operation, DataTypeRegistry dataTypeRegistry, ApiDescription apiDescription) { var methodNode = _navigator.SelectSingleNode(GetXPathFor(apiDescription.ActionDescriptor)); operation.Summary = GetChildValueOrDefault(methodNode, SummaryExpression); operation.Notes = GetChildValueOrDefault(methodNode, RemarksExpression); foreach (var paramDesc in apiDescription.ParameterDescriptions) { if (paramDesc.ParameterDescriptor == null) continue; // not in action signature (e.g. route parameter) var parameter = operation.Parameters.SingleOrDefault(p => p.Name == paramDesc.Name); if (parameter == null) continue; parameter.Description = GetChildValueOrDefault( methodNode, String.Format(ParameterExpression, paramDesc.ParameterDescriptor.ParameterName)); } if (methodNode == null) return; foreach (var responseMessage in GetResponseMessages(methodNode)) { operation.ResponseMessages.Add(responseMessage); } }
/// <summary> /// Gets the model that represents an API displayed on the help page. The model is initialized on the first call and cached for subsequent calls. /// </summary> /// <param name="config">The <see cref="T:System.Web.Http.HttpConfiguration" />.</param> /// <param name="explorer">The API explorer containing all known controllers.</param> /// <param name="apiDescriptionId">The API description ID as specified in /// <see cref="M:Geocrest.Web.Mvc.Documentation.ApiDescriptionExtensions.GetFriendlyId(System.Web.Http.Description.ApiDescription,System.String)"/>.</param> /// <param name="homePage">The home page url.</param> /// <param name="version">The version number to display.</param> /// <returns> /// An <see cref="HelpPageApiModel" /> /// </returns> public static HelpPageApiModel GetHelpPageApiModel(this HttpConfiguration config, IApiExplorer explorer, string apiDescriptionId, string homePage = "", string version = "") { object model; apiDescriptionId += !string.IsNullOrEmpty(version) ? "-" + version : ""; string modelId = ApiModelPrefix + apiDescriptionId; if (!config.Properties.TryGetValue(modelId, out model)) { Collection <System.Web.Http.Description.ApiDescription> apiDescriptions = explorer.ApiDescriptions; System.Web.Http.Description.ApiDescription apiDescription = apiDescriptions.FirstOrDefault(api => String.Equals(api.GetFriendlyId(version), apiDescriptionId, StringComparison.OrdinalIgnoreCase)); if (apiDescription != null) { HelpPageSampleGenerator sampleGenerator = config.GetHelpPageSampleGenerator(); model = GenerateApiModel(apiDescription, sampleGenerator, config, homePage); config.Properties.TryAdd(modelId, model); if (string.IsNullOrEmpty(((HelpPageApiModel)model).HomePageUrl) && !string.IsNullOrEmpty(homePage)) { ((HelpPageApiModel)model).HomePageUrl = homePage; } } } return((HelpPageApiModel)model); }
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { if (operation == null) { throw new ArgumentNullException("operation"); } if (apiDescription == null) { throw new ArgumentNullException("apiDescription"); } // Correspond each "Authorize" action to an oauth2 scope var authorized = apiDescription.ActionDescriptor.GetFilterPipeline() .Select(filterInfo => filterInfo.Instance) .OfType<AuthorizeAttribute>() .Distinct(); if (authorized.Any()) { if (operation.security == null) { operation.security = new List<IDictionary<string, IEnumerable<string>>>(); } var requirements = new Dictionary<string, IEnumerable<string>> { { this.provider, new string[] { } } }; operation.security.Add(requirements); } }
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { // Determine if the operation has the Authorize attribute var authorizeAttributes = apiDescription .ActionDescriptor.GetCustomAttributes<AuthorizeAttribute>(); if (!authorizeAttributes.Any()) return; // Correspond each "Authorize" role to an oauth2 scope var scopes = authorizeAttributes .SelectMany(attr => attr.Roles.Split(',')) .Distinct() .ToList(); // Initialize the operation.security property if it hasn't already been if (operation.security == null) operation.security = new List<IDictionary<string, IEnumerable<string>>>(); var oAuthRequirements = new Dictionary<string, IEnumerable<string>> { { "oauth2", scopes } }; operation.security.Add(oAuthRequirements); }
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { var hasAuthorizeAttr = apiDescription.ActionDescriptor.GetFilterPipeline() .Select(filterInfo => filterInfo.Instance) .Any(filter => filter is IAuthorizationFilter); var hasAllowAnonymous = apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any(); if (hasAuthorizeAttr && !hasAllowAnonymous) { if (operation.parameters == null) { operation.parameters = new List<Parameter>(); } operation.parameters.Add(new Parameter() { description = "Authorization token. Used for applying content access restrictions. Use one of the OAuth2 grants to auto-populate this value.", @in = "header", name = "Authorization", required = true, type = "string", @default = "bearer " }); } }
public void MobileAppAuthFilter_AddsSecurity_WhenAuthorizeSpecified() { // Arrange var filter = new MobileAppAuthenticationFilter("facebook"); var operation = new Operation(); var apiDescription = new ApiDescription(); var actionDescMock = new Mock<HttpActionDescriptor>(); Collection<FilterInfo> pipeline = new Collection<FilterInfo>() { new FilterInfo(new AuthorizeAttribute(), FilterScope.Action) }; actionDescMock.Setup(a => a.GetFilterPipeline()).Returns(pipeline); apiDescription.ActionDescriptor = actionDescMock.Object; // Act filter.Apply(operation, null, apiDescription); // Assert Assert.NotNull(operation.security); Assert.Equal(1, operation.security.Count); Assert.Equal(1, operation.security[0].Keys.Count); Assert.Equal("facebook", operation.security[0].Keys.First()); Assert.Equal(0, operation.security[0]["facebook"].Count()); }
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { var descriptor = apiDescription.ActionDescriptor as ControllerlessActionDescriptor; operation.summary = descriptor != null ? this.provider.GetDescription(descriptor.MessageType) : operation.summary; }
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { if (operation.operationId != "Products_GetAllByType") return; var response = operation.responses["200"]; response.vendorExtensions = new Dictionary<string, object>(); response.vendorExtensions.Add("x-foo", "bar"); }
public void ApiDescription_Property() { HelpPageApiModel model = new HelpPageApiModel(); ApiDescription description = new ApiDescription(); model.ApiDescription = description; Assert.NotNull(model.ApiDescription); Assert.Same(description, model.ApiDescription); }
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { var successResponse = operation.responses["200"]; successResponse.examples = new Dictionary<string, object> { {"application/json", new {title = "A message", content = "Some content"}} }; }
private static string GetGroupName(ApiDescription apiDescription) { var controllerType = apiDescription.ActionDescriptor .ControllerDescriptor .ControllerType; return GetGroupName(controllerType); }
private void PopulateActionDescriptions(HttpActionDescriptor actionDescriptor, IHttpRoute route, string localPath, Collection <System.Web.Http.Description.ApiDescription> apiDescriptions) { string apiDocumentation = GetApiDocumentation(actionDescriptor); // parameters IList <System.Web.Http.Description.ApiParameterDescription> parameterDescriptions = CreateParameterDescriptions(actionDescriptor); // expand all parameter variables string finalPath; if (!TryExpandUriParameters(route, actionDescriptor, parameterDescriptions, out finalPath)) { // the action cannot be reached due to parameter mismatch, e.g. routeTemplate = "/users/{name}" and GetUsers(id) return; } // request formatters System.Web.Http.Description.ApiParameterDescription bodyParameter = parameterDescriptions.FirstOrDefault(description => description.Source == ApiParameterSource.FromBody); IEnumerable <MediaTypeFormatter> supportedRequestBodyFormatters = bodyParameter != null? actionDescriptor.Configuration.Formatters.Where(f => f.CanReadType(bodyParameter.ParameterDescriptor.ParameterType)) : Enumerable.Empty <MediaTypeFormatter>(); // response formatters Type returnType = actionDescriptor.ReturnType; IEnumerable <MediaTypeFormatter> supportedResponseFormatters = returnType != null? actionDescriptor.Configuration.Formatters.Where(f => f.CanWriteType(returnType)) : Enumerable.Empty <MediaTypeFormatter>(); // get HttpMethods supported by an action. Usually there is one HttpMethod per action but we allow multiple of them per action as well. IList <HttpMethod> supportedMethods = this.GetHttpMethodsSupportedByAction(route, actionDescriptor); foreach (HttpMethod method in supportedMethods) { var description = new System.Web.Http.Description.ApiDescription() { Documentation = apiDocumentation, HttpMethod = method, RelativePath = finalPath, ActionDescriptor = actionDescriptor, Route = route }; foreach (var mtf in supportedRequestBodyFormatters) { description.SupportedRequestBodyFormatters.Add(mtf); } foreach (var mtf in supportedResponseFormatters) { description.SupportedResponseFormatters.Add(mtf); } foreach (var par in parameterDescriptions) { description.ParameterDescriptions.Add(par); } apiDescriptions.Add(description); } }
private IEnumerable<Type> GetTypeOfActionParameters(ApiDescription apiDescription) { var parameters = apiDescription.ActionDescriptor.GetParameters(); var paramTypes = new List<Type>(); if (parameters != null) parameters.ToList().ForEach(p => paramTypes.Add(p.ParameterType)); return paramTypes; }
///// <summary> ///// Gets the HTML sample associated with a given <see cref="T:System.Web.Http.Description.ApiDescription" />. ///// </summary> ///// <param name="api">The API description containing the route values.</param> ///// <returns> ///// The associated <see cref="T:Geocrest.Web.Mvc.Documentation.HtmlSample" />. ///// </returns> ///// <exception cref="System.ArgumentNullException">api</exception> //public virtual HtmlSample GetHtmlSample(System.Web.Http.Description.ApiDescription api) //{ // Throw.IfArgumentNull(api, "api"); // string controllerName = api.ActionDescriptor.ControllerDescriptor.ControllerName; // string actionName = api.ActionDescriptor.ActionName; // IEnumerable<string> parameterNames = api.ParameterDescriptions.Select(p => p.Name); // return GetHtmlSample(controllerName, actionName, parameterNames); //} /// <summary> /// Gets the HTML samples associated with a given <see cref="T:System.Web.Http.Description.ApiDescription" />. /// </summary> /// <param name="api">The API description containing the route values.</param> /// <returns> /// Returns a collection of <see cref="T:Geocrest.Web.Mvc.Documentation.HtmlSample"/>s. /// </returns> /// <exception cref="T:System.ArgumentNullException">api</exception> public virtual IEnumerable <HtmlSample> GetHtmlSamples(System.Web.Http.Description.ApiDescription api) { Throw.IfArgumentNull(api, "api"); string controllerName = api.ActionDescriptor.ControllerDescriptor.ControllerName; string actionName = api.ActionDescriptor.ActionName; IEnumerable <string> parameterNames = api.ParameterDescriptions.Select(p => p.Name); return(GetHtmlSamples(controllerName, actionName, parameterNames)); }
public ApiEndpointModel(ApiDescription desc, UrlHelper url, HttpRequestBase request) { this.Documentation = desc.Documentation; this.Controller = desc.ActionDescriptor.ControllerDescriptor.ControllerName; this.Action = desc.ActionDescriptor.ActionName; this.Method = desc.HttpMethod.Method; this.Path = url.Action(this.Action, this.Controller, new { }, request.Url.Scheme); this.Parameters = desc.ParameterDescriptions.Select(p => new ApiEndpointParameterModel(p)); }
public void Apply(Operation operation, DataTypeRegistry dataTypeRegistry, ApiDescription apiDescription) { if (_errorStatusCodes == null) return; _errorStatusCodes.ToList().ForEach(e => operation.ResponseMessages.Add(new ResponseMessage { Code = (int)e, Message = Regex.Replace(Enum.GetName(typeof(HttpStatusCode), e), @"([a-z])([A-Z])", @"$1 $2", RegexOptions.None), })); }
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { var errorSchema = schemaRegistry.GetOrRegister(typeof(HttpError)); operation.responses.Add("200", new Response { description = "Ok", schema = errorSchema }); }
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { var attributes = apiDescription.GetControllerAndActionAttributes<SwaggerOperationFilterAttribute>(); foreach (var attribute in attributes) { var filter = (IOperationFilter)Activator.CreateInstance(attribute.FilterType); filter.Apply(operation, schemaRegistry, apiDescription); } }
public static List<string> GetRelList(MappingRule mapping, ApiDescription apiDescription, List<string> rels) { var result = new List<string>(rels); var returnType = mapping.MethodExpression.Method.ReturnType; if (returnType.IsGenericType && typeof(IEnumerable<>).IsAssignableFrom(returnType.GetGenericTypeDefinition())) result.Add(SirenMetadataProvider.QueryClassName); return result; }
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; }
/// <summary> /// Gets the request or response body samples. /// </summary> /// <param name="api">The <see cref="T:System.Web.Http.Description.ApiDescription"/>.</param> /// <param name="sampleDirection">The value indicating whether the sample is for a request or for a response.</param> /// <returns>The samples keyed by media type.</returns> /// <exception cref="System.ArgumentNullException">api</exception> public virtual IDictionary <MediaTypeHeaderValue, object> GetSample(System.Web.Http.Description.ApiDescription api, SampleDirection sampleDirection) { Throw.IfArgumentNull(api, "api"); string controllerName = api.ActionDescriptor.ControllerDescriptor.ControllerName; string actionName = api.ActionDescriptor.ActionName; IEnumerable <string> parameterNames = api.ParameterDescriptions.Select(p => p.Name); Collection <MediaTypeFormatter> formatters; Type type = ResolveType(api, controllerName, actionName, parameterNames, sampleDirection, out formatters); var samples = new Dictionary <MediaTypeHeaderValue, object>(); // Use the samples provided directly for actions var actionSamples = GetAllActionSamples(api, parameterNames, sampleDirection); foreach (var actionSample in actionSamples) { samples.Add(actionSample.Key.MediaType, WrapSampleIfString(actionSample.Value)); } // Do the sample generation based on formatters only if an action doesn't return an HttpResponseMessage. // Here we cannot rely on formatters because we don't know what's in the HttpResponseMessage, it might not even use formatters. if (type != null && !typeof(HttpResponseMessage).IsAssignableFrom(type)) { object sampleObject = GetSampleObject(type); foreach (var formatter in formatters) { foreach (MediaTypeHeaderValue mediaType in formatter.SupportedMediaTypes) { if (!samples.ContainsKey(mediaType)) { object sample = GetActionSample(controllerName, actionName, parameterNames, type, mediaType, sampleDirection); // If no sample found, try generate sample using formatter and sample object if (sample == null && sampleObject != null) { sample = WriteSampleObjectUsingFormatter(api, formatter, sampleObject, type, mediaType); } samples.Add(mediaType, WrapSampleIfString(sample, formatter)); } } } } return(samples); }
private static HelpPageApiModel GenerateApiModel(System.Web.Http.Description.ApiDescription apiDescription, HelpPageSampleGenerator sampleGenerator, HttpConfiguration configuration, string homePage) { HelpPageApiModel apiModel = new HelpPageApiModel(homePage); apiModel.ApiDescription = apiDescription; if (apiModel.ApiDescription.RelativePath.EndsWith("/")) { apiModel.ApiDescription.RelativePath = apiModel.ApiDescription.RelativePath.Substring(0, apiModel.ApiDescription.RelativePath.Length - 1); } try { IResponseDocumentationProvider responseDocProvider = (IResponseDocumentationProvider)configuration.Services.GetDocumentationProvider(); if (responseDocProvider != null) { apiModel.ResponseDocumentation = responseDocProvider.GetResponseDocumentation(apiDescription.ActionDescriptor); } foreach (var item in sampleGenerator.GetSampleRequests(apiDescription)) { apiModel.SampleRequests.Add(item.Key, item.Value); LogInvalidSampleAsError(apiModel, item.Value); } foreach (var item in sampleGenerator.GetSampleResponses(apiDescription)) { apiModel.SampleResponses.Add(item.Key, item.Value); LogInvalidSampleAsError(apiModel, item.Value); } foreach (var item in sampleGenerator.GetHtmlSamples(apiDescription)) { apiModel.HtmlSamples.AddIfNotNull <HtmlSample>(item); LogInvalidSampleAsError(apiModel, item); } } catch (Exception e) { apiModel.ErrorMessages.Add(String.Format(CultureInfo.CurrentCulture, "An exception has occurred while generating the sample. Exception Message: {0}", e.Message)); } return(apiModel); }
public virtual Type ResolveType(System.Web.Http.Description.ApiDescription api, string controllerName, string actionName, IEnumerable <string> parameterNames, SampleDirection sampleDirection, out Collection <MediaTypeFormatter> formatters) { Throw.IfEnumNotDefined <SampleDirection>(sampleDirection, "sampleDirection"); Throw.IfArgumentNull(api, "api"); Type type; if (ActualHttpMessageTypes.TryGetValue(new HelpPageSampleKey(sampleDirection, controllerName, actionName, parameterNames), out type) || ActualHttpMessageTypes.TryGetValue(new HelpPageSampleKey(sampleDirection, controllerName, actionName, new string[] { }), out type)) { // Re-compute the supported formatters based on type Collection <MediaTypeFormatter> newFormatters = new Collection <MediaTypeFormatter>(); foreach (var formatter in api.ActionDescriptor.Configuration.Formatters) { if (IsFormatSupported(sampleDirection, formatter, type)) { newFormatters.Add(formatter); } } formatters = newFormatters; } else { switch (sampleDirection) { case SampleDirection.Request: System.Web.Http.Description.ApiParameterDescription requestBodyParameter = api.ParameterDescriptions.FirstOrDefault(p => p.Source == ApiParameterSource.FromBody); type = requestBodyParameter == null ? null : requestBodyParameter.ParameterDescriptor.ParameterType; formatters = api.SupportedRequestBodyFormatters; break; case SampleDirection.Response: default: type = api.ActionDescriptor.ReturnType; formatters = api.SupportedResponseFormatters; break; } } return(type); }
public void Apply(Operation operation, SchemaRegistry schemaRegistry, System.Web.Http.Description.ApiDescription apiDescription) { if (operation.operationId.IndexOf("Trigger", StringComparison.InvariantCultureIgnoreCase) >= 0) { // this is a possible trigger var triggerStateParam = operation.parameters.FirstOrDefault(x => x.name.Equals("triggerState")); if (triggerStateParam != null) { if (triggerStateParam.vendorExtensions == null) { triggerStateParam.vendorExtensions = new Dictionary <string, object>(); } // add 2 vendor extensions // x-ms-visibility: set to 'internal' to signify this is an internal field // x-ms-scheduler-recommendation: set to a value that logic app can use triggerStateParam.vendorExtensions.Add("x-ms-visibility", "internal"); triggerStateParam.vendorExtensions.Add("x-ms-scheduler-recommendation", "@coalesce(triggers()?.outputs?.body?['triggerState'], '')"); } } }
public void Apply(Operation operation, SchemaRegistry schemaRegistry, System.Web.Http.Description.ApiDescription apiDescription) { if (operation.parameters == null) { // no parameter return; } foreach (var param in operation.parameters) { var summaryAttributes = apiDescription.ParameterDescriptions.First(x => x.Name.Equals(param.name)) .ParameterDescriptor.GetCustomAttributes <CustomSummaryAttribute>(); if (summaryAttributes != null && summaryAttributes.Count > 0) { // add x-ms-summary extension if (param.vendorExtensions == null) { param.vendorExtensions = new Dictionary <string, object>(); } param.vendorExtensions.Add("x-ms-summary", summaryAttributes[0].SummaryText); } } }
/// <summary> /// Gets the response body samples for a given <see cref="T:System.Web.Http.Description.ApiDescription"/>. /// </summary> /// <param name="api">The <see cref="System.Web.Http.Description.ApiDescription"/>.</param> /// <returns>The samples keyed by media type.</returns> public IDictionary <MediaTypeHeaderValue, object> GetSampleResponses(System.Web.Http.Description.ApiDescription api) { return(GetSample(api, SampleDirection.Response)); }
public void Apply(Operation operation, DataTypeRegistry dataTypeRegistry, System.Web.Http.Description.ApiDescription apiDescription) { operation.ResponseMessages.Add(new ResponseMessage { Code = 200, Message = "It's all good!" }); }
public virtual object WriteSampleObjectUsingFormatter(System.Web.Http.Description.ApiDescription api, MediaTypeFormatter formatter, object value, Type type, MediaTypeHeaderValue mediaType) { Throw.IfArgumentNull(formatter, "formatter"); Throw.IfArgumentNull(mediaType, "mediaType"); object sample = String.Empty; MemoryStream ms = null; HttpContent content = null; try { if (formatter.CanWriteType(type)) { ms = new MemoryStream(); content = new ObjectContent(type, value, formatter, mediaType); var request = new HttpRequestMessage(HttpMethod.Get, api.RelativePath.ToAbsoluteUrl()); request.Properties["MS_HttpConfiguration"] = GlobalConfiguration.Configuration; request.Properties["MS_HttpRouteData"] = api.Route.GetRouteData( GlobalConfiguration.Configuration.VirtualPathRoot, request); request.Properties["MS_HttpContext"] = new HttpContextWrapper(HttpContext.Current); UrlHelper helper = new UrlHelper(request); var enrichers = GlobalConfiguration.Configuration.GetResponseEnrichers(); var enriched = enrichers.Where(e => e.CanEnrich(type, helper, mediaType)) .Aggregate(value, (url, enricher) => enricher.Enrich(api.RelativePath.ToAbsoluteUrl(), helper, value)); formatter.WriteToStreamAsync(type, enriched, ms, content, null).Wait(); ms.Position = 0; StreamReader reader = new StreamReader(ms); string serializedSampleString = reader.ReadToEnd(); if (mediaType.MediaType.ToUpperInvariant().Contains("XML")) { serializedSampleString = TryFormatXml(serializedSampleString); } else if (mediaType.MediaType.ToUpperInvariant().Contains("JSON")) { serializedSampleString = TryFormatJson(serializedSampleString); } sample = new TextSample(serializedSampleString, formatter.SupportedMediaTypes); } else { sample = new InvalidSample(String.Format( CultureInfo.CurrentCulture, "Failed to generate the sample for media type '{0}'. Cannot use formatter '{1}' to write type '{2}'.", mediaType, formatter.GetType().Name, type.Name)); } } catch (Exception e) { sample = new InvalidSample(String.Format( CultureInfo.CurrentCulture, "An exception has occurred while using the formatter '{0}' to generate sample for media type '{1}'. Exception message: {2}", formatter.GetType().Name, mediaType.MediaType, e.GetExceptionMessages())); } finally { if (ms != null) { ms.Dispose(); } if (content != null) { content.Dispose(); } } return(sample); }
private IEnumerable <KeyValuePair <HelpPageSampleKey, object> > GetAllActionSamples(System.Web.Http.Description.ApiDescription api, IEnumerable <string> parameterNames, SampleDirection sampleDirection) { HashSet <string> parameterNamesSet = new HashSet <string>(parameterNames, StringComparer.OrdinalIgnoreCase); foreach (var sample in ActionSamples) { HelpPageSampleKey sampleKey = sample.Key; if (String.Equals(api.ActionDescriptor.ControllerDescriptor.ControllerName, sampleKey.ControllerName, StringComparison.OrdinalIgnoreCase) && String.Equals(api.ActionDescriptor.ActionName, sampleKey.ActionName, StringComparison.OrdinalIgnoreCase) && api.ParameterDescriptions.Count == sampleKey.ParameterNames.Count && api.ParameterDescriptions.All(x => sampleKey.ParameterNames.Contains(x.Name)) && //(sampleKey.ParameterNames.SetEquals(new string[] { }) || parameterNamesSet.SetEquals(sampleKey.ParameterNames)) && sampleDirection == sampleKey.SampleDirection) { yield return(sample); } } }