private DataContract ConvertMessage(MessageDescriptor messageDescriptor) { if (IsWellKnownType(messageDescriptor)) { if (IsWrapperType(messageDescriptor)) { var field = messageDescriptor.Fields[Int32Value.ValueFieldNumber]; return(_innerContractResolver.GetDataContractForType(MessageDescriptorHelpers.ResolveFieldType(field))); } if (messageDescriptor.FullName == Timestamp.Descriptor.FullName || messageDescriptor.FullName == Duration.Descriptor.FullName || messageDescriptor.FullName == FieldMask.Descriptor.FullName) { return(DataContract.ForPrimitive(messageDescriptor.ClrType, DataType.String, dataFormat: null)); } if (messageDescriptor.FullName == Struct.Descriptor.FullName) { return(DataContract.ForObject(messageDescriptor.ClrType, Array.Empty <DataProperty>(), extensionDataType: typeof(Value))); } if (messageDescriptor.FullName == ListValue.Descriptor.FullName) { return(DataContract.ForArray(messageDescriptor.ClrType, typeof(Value))); } if (messageDescriptor.FullName == Value.Descriptor.FullName) { return(DataContract.ForPrimitive(messageDescriptor.ClrType, DataType.Unknown, dataFormat: null)); } if (messageDescriptor.FullName == Any.Descriptor.FullName) { var anyProperties = new List <DataProperty> { new DataProperty("@type", typeof(string), isRequired: true) }; return(DataContract.ForObject(messageDescriptor.ClrType, anyProperties, extensionDataType: typeof(Value))); } } var properties = new List <DataProperty>(); foreach (var field in messageDescriptor.Fields.InFieldNumberOrder()) { // Enum type will later be used to call this contract resolver. // Register the enum type so we know to resolve its names from the descriptor. if (field.FieldType == FieldType.Enum) { _enumTypeMapping.TryAdd(field.EnumType.ClrType, field.EnumType); } Type fieldType; if (field.IsMap) { var mapFields = field.MessageType.Fields.InFieldNumberOrder(); var valueType = MessageDescriptorHelpers.ResolveFieldType(mapFields[1]); fieldType = typeof(IDictionary <,>).MakeGenericType(typeof(string), valueType); } else if (field.IsRepeated) { fieldType = typeof(IList <>).MakeGenericType(MessageDescriptorHelpers.ResolveFieldType(field)); } else { fieldType = MessageDescriptorHelpers.ResolveFieldType(field); } properties.Add(new DataProperty(field.JsonName, fieldType)); } var schema = DataContract.ForObject(messageDescriptor.ClrType, properties: properties); return(schema); }
private static ApiDescription CreateApiDescription(RouteEndpoint routeEndpoint, HttpRule httpRule, MethodDescriptor methodDescriptor, string pattern, string verb) { var apiDescription = new ApiDescription(); apiDescription.HttpMethod = verb; apiDescription.ActionDescriptor = new ActionDescriptor { RouteValues = new Dictionary <string, string> { // Swagger uses this to group endpoints together. // Group methods together using the service name. ["controller"] = methodDescriptor.Service.FullName } }; apiDescription.RelativePath = pattern.TrimStart('/'); apiDescription.SupportedRequestFormats.Add(new ApiRequestFormat { MediaType = "application/json" }); apiDescription.SupportedResponseTypes.Add(new ApiResponseType { ApiResponseFormats = { new ApiResponseFormat { MediaType = "application/json" } }, ModelMetadata = new GrpcModelMetadata(ModelMetadataIdentity.ForType(methodDescriptor.OutputType.ClrType)), StatusCode = 200 }); var routeParameters = ServiceDescriptorHelpers.ResolveRouteParameterDescriptors(routeEndpoint.RoutePattern, methodDescriptor.InputType); foreach (var routeParameter in routeParameters) { var field = routeParameter.Value.Last(); apiDescription.ParameterDescriptions.Add(new ApiParameterDescription { Name = routeParameter.Key, ModelMetadata = new GrpcModelMetadata(ModelMetadataIdentity.ForType(MessageDescriptorHelpers.ResolveFieldType(field))), Source = BindingSource.Path, DefaultValue = string.Empty }); } ServiceDescriptorHelpers.ResolveBodyDescriptor(httpRule.Body, methodDescriptor, out var bodyDescriptor, out _, out _); if (bodyDescriptor != null) { apiDescription.ParameterDescriptions.Add(new ApiParameterDescription { Name = "Input", ModelMetadata = new GrpcModelMetadata(ModelMetadataIdentity.ForType(bodyDescriptor.ClrType)), Source = BindingSource.Body }); } return(apiDescription); }
private static ApiDescription CreateApiDescription(RouteEndpoint routeEndpoint, HttpRule httpRule, MethodDescriptor methodDescriptor, string pattern, string verb) { var apiDescription = new ApiDescription(); apiDescription.HttpMethod = verb; apiDescription.ActionDescriptor = new ActionDescriptor { RouteValues = new Dictionary <string, string?> { // Swagger uses this to group endpoints together. // Group methods together using the service name. ["controller"] = methodDescriptor.Service.FullName }, EndpointMetadata = routeEndpoint.Metadata.ToList() }; apiDescription.RelativePath = pattern.TrimStart('/'); apiDescription.SupportedRequestFormats.Add(new ApiRequestFormat { MediaType = "application/json" }); apiDescription.SupportedResponseTypes.Add(new ApiResponseType { ApiResponseFormats = { new ApiResponseFormat { MediaType = "application/json" } }, ModelMetadata = new GrpcModelMetadata(ModelMetadataIdentity.ForType(methodDescriptor.OutputType.ClrType)), StatusCode = 200 }); var explorerSettings = routeEndpoint.Metadata.GetMetadata <ApiExplorerSettingsAttribute>(); if (explorerSettings != null) { apiDescription.GroupName = explorerSettings.GroupName; } var methodMetadata = routeEndpoint.Metadata.GetMetadata <GrpcMethodMetadata>() !; var routeParameters = ServiceDescriptorHelpers.ResolveRouteParameterDescriptors(routeEndpoint.RoutePattern, methodDescriptor.InputType); foreach (var routeParameter in routeParameters) { var field = routeParameter.Value.Last(); var parameterName = ServiceDescriptorHelpers.FormatUnderscoreName(field.Name, pascalCase: true, preservePeriod: false); var propertyInfo = field.ContainingType.ClrType.GetProperty(parameterName); // If from a property, create model as property to get its XML comments. var identity = propertyInfo != null ? ModelMetadataIdentity.ForProperty(propertyInfo, MessageDescriptorHelpers.ResolveFieldType(field), field.ContainingType.ClrType) : ModelMetadataIdentity.ForType(MessageDescriptorHelpers.ResolveFieldType(field)); apiDescription.ParameterDescriptions.Add(new ApiParameterDescription { Name = routeParameter.Key, ModelMetadata = new GrpcModelMetadata(identity), Source = BindingSource.Path, DefaultValue = string.Empty }); } var bodyDescriptor = ServiceDescriptorHelpers.ResolveBodyDescriptor(httpRule.Body, methodMetadata.ServiceType, methodDescriptor); if (bodyDescriptor != null) { // If from a property, create model as property to get its XML comments. var identity = bodyDescriptor.PropertyInfo != null ? ModelMetadataIdentity.ForProperty(bodyDescriptor.PropertyInfo, bodyDescriptor.Descriptor.ClrType, bodyDescriptor.PropertyInfo.DeclaringType !) : ModelMetadataIdentity.ForType(bodyDescriptor.Descriptor.ClrType); // Or if from a parameter, create model as parameter to get its XML comments. var parameterDescriptor = bodyDescriptor.ParameterInfo != null ? new ControllerParameterDescriptor { ParameterInfo = bodyDescriptor.ParameterInfo } : null; apiDescription.ParameterDescriptions.Add(new ApiParameterDescription { Name = "Input", ModelMetadata = new GrpcModelMetadata(identity), Source = BindingSource.Body, ParameterDescriptor = parameterDescriptor ! });