예제 #1
0
    private DataContract ConvertMessage(MessageDescriptor messageDescriptor)
    {
        if (ServiceDescriptorHelpers.IsWellKnownType(messageDescriptor))
        {
            if (ServiceDescriptorHelpers.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);
            }

            var propertyName = ServiceDescriptorHelpers.FormatUnderscoreName(field.Name, pascalCase: true, preservePeriod: false);
            var propertyInfo = messageDescriptor.ClrType.GetProperty(propertyName);

            properties.Add(new DataProperty(field.JsonName, fieldType, memberInfo: propertyInfo));
        }

        var schema = DataContract.ForObject(messageDescriptor.ClrType, properties: properties);

        return(schema);
    }
예제 #2
0
    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 !
            });
예제 #3
0
        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(new DataContract(DataType.String, messageDescriptor.ClrType));
                }
                if (messageDescriptor.FullName == Struct.Descriptor.FullName)
                {
                    return(new DataContract(DataType.Object, messageDescriptor.ClrType, additionalPropertiesType: typeof(Value)));
                }
                if (messageDescriptor.FullName == ListValue.Descriptor.FullName)
                {
                    return(new DataContract(DataType.Array, messageDescriptor.ClrType, arrayItemType: typeof(Value)));
                }
                if (messageDescriptor.FullName == Value.Descriptor.FullName)
                {
                    return(new DataContract(DataType.Unknown, messageDescriptor.ClrType));
                }
                if (messageDescriptor.FullName == Any.Descriptor.FullName)
                {
                    var anyProperties = new List <DataProperty>
                    {
                        new DataProperty("@type", typeof(string), isRequired: true)
                    };
                    return(new DataContract(DataType.Object, messageDescriptor.ClrType, properties: anyProperties, additionalPropertiesType: 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 = new DataContract(DataType.Object, messageDescriptor.ClrType, properties: properties);

            return(schema);
        }