private void AddBodyParameter(SwaggerOperationExtended operation, ISchemaResolver schemaResolver, ParameterInfo parameter) { var operationParameter = CreateBodyParameter(parameter, schemaResolver); operation.Parameters.Add(operationParameter); }
private void AddPrimitiveParameter(SwaggerOperationExtended operation, ISchemaResolver schemaResolver, ParameterInfo parameter) { var operationParameter = CreatePrimitiveParameter(parameter, schemaResolver); operationParameter.Kind = SwaggerParameterKindExtended.Query; operation.Parameters.Add(operationParameter); }
private void LoadReturnType(SwaggerOperationExtended operation, MethodInfo method, ISchemaResolver schemaResolver) { if (method.ReturnType.FullName != "System.Void" && method.ReturnType.FullName != "System.Threading.Tasks.Task") { operation.Responses["200"] = new SwaggerResponse { Schema = CreateAndAddSchema <JsonSchema4>(method.ReturnType, schemaResolver) }; } else { operation.Responses["200"] = new SwaggerResponse(); } }
private string GetHttpPath(SwaggerOperationExtended operation, MethodInfo method, List <ParameterInfo> parameters, ISchemaResolver schemaResolver) { string httpPath; dynamic routeAttribute = method.GetCustomAttributes() .SingleOrDefault(a => a.GetType().Name == "RouteAttribute"); if (routeAttribute != null) { dynamic routePrefixAttribute = _serviceType.GetCustomAttributes() .SingleOrDefault(a => a.GetType().Name == "RoutePrefixAttribute"); if (routePrefixAttribute != null) { httpPath = routePrefixAttribute.Prefix + "/" + routeAttribute.Template; } else { httpPath = routeAttribute.Template; } } else { httpPath = DefaultRouteTemplate .Replace("{controller}", _serviceType.Name.Replace("AppService", string.Empty)) .Replace("{action}", method.Name); } foreach (var match in Regex.Matches(httpPath, "\\{(.*?)\\}").OfType <Match>()) { var parameter = parameters.SingleOrDefault(p => p.Name == match.Groups[1].Value); if (parameter != null) { var operationParameter = CreatePrimitiveParameter(parameter, schemaResolver); operationParameter.Kind = SwaggerParameterKindExtended.Path; operation.Parameters.Add(operationParameter); parameters.Remove(parameter); } else { httpPath = "/" + httpPath .Replace(match.Value, string.Empty) .Replace("//", "/") .Trim('/'); } } return(httpPath); }
private void LoadMetaData(SwaggerOperationExtended operation, MethodInfo method) { dynamic descriptionAttribute = method.GetCustomAttributes() .SingleOrDefault(a => a.GetType().Name == "WebApiDescriptionAttribute"); if (descriptionAttribute != null) { operation.Summary = descriptionAttribute.Description; } else { var summary = method.GetXmlDocumentation(); if (summary != string.Empty) { operation.Summary = summary; } } }
private void LoadParameters(SwaggerOperationExtended operation, IEnumerable <ParameterInfo> parameters, ISchemaResolver schemaResolver) { foreach (var parameter in parameters) { var info = JsonObjectTypeDescription.FromType(parameter.ParameterType); dynamic fromBodyAttribute = parameter.GetCustomAttributes() .SingleOrDefault(a => a.GetType().Name == "FromBodyAttribute"); dynamic fromUriAttribute = parameter.GetCustomAttributes() .SingleOrDefault(a => a.GetType().Name == "FromUriAttribute"); // TODO: Add support for ModelBinder attribute var isComplexParameter = IsComplexType(info); if (isComplexParameter) { if (fromUriAttribute != null) { AddPrimitiveParameter(operation, schemaResolver, parameter); } else { AddBodyParameter(operation, schemaResolver, parameter); } } else { if (fromBodyAttribute != null) { AddBodyParameter(operation, schemaResolver, parameter); } else { AddPrimitiveParameter(operation, schemaResolver, parameter); } } } if (operation.Parameters.Count(p => p.Kind == SwaggerParameterKindExtended.Body) > 1) { throw new InvalidOperationException("The operation '" + operation.OperationId + "' has more than one body parameter."); } }
/// <summary> /// 生成文档结构 /// </summary> /// <param name="type">具体的 AppService 类型</param> /// <param name="interfaceType">具体的 IAppService 类型</param> /// <param name="excludedMethodName">排除的方法名称</param> /// <returns></returns> public SwaggerServiceExtended GenerateForAbpAppService(Type type, Type interfaceType, string excludedMethodName = "Swagger") { _service = new SwaggerServiceExtended(); _serviceType = type; var schemaResolver = new SchemaResolver(); var deriveMethods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); var methods = interfaceType.GetMethods(); dynamic webApiDesc = interfaceType.GetCustomAttributes() .FirstOrDefault(x => x.GetType().Name == "WebApiDescriptionAttribute"); if (webApiDesc != null) { dynamic name = webApiDesc.Name; dynamic description = webApiDesc.Description; _service.Tags.Add(new SwaggerTagInfo { Name = name, Description = description }); } var hasGenerated = false; foreach (var method in methods.Where(m => m.Name != excludedMethodName)) { //根据特性判断是否是公共的WebAPI方法 var canOpen = method.GetCustomAttributes().Any(x => x.GetType().Name == "OpenWebApiAttribute"); if (!canOpen) { continue; } var driveMethod = GetSpecifiedMethod(deriveMethods, method); var parameters = method.GetParameters().ToList(); var methodName = method.Name; var operation = new SwaggerOperationExtended { OperationId = methodName }; dynamic webApiMethodDesc = method.GetCustomAttributes().FirstOrDefault(x => x.GetType().Name == "WebApiDescriptionAttribute"); if (webApiMethodDesc != null) { operation.Tags.Add(webApiMethodDesc.Name); } var httpPath = GetHttpPath(operation, driveMethod, parameters, schemaResolver); LoadParameters(operation, parameters, schemaResolver); LoadReturnType(operation, driveMethod, schemaResolver); LoadMetaData(operation, method); var httpMethod = GetMethod(method); if (!_service.Paths.ContainsKey(httpPath)) { var path = new SwaggerOperationsExtended(); _service.Paths[httpPath] = path; } _service.Paths[httpPath][httpMethod] = operation; hasGenerated = true; } foreach (var schema in schemaResolver.Schemes) { _service.Definitions[schema.TypeName] = schema; } _service.GenerateOperationIds(); if (!hasGenerated) { _service = null; } return(_service); }