diff --git a/src/Core/Services/MetadataProviders/SqlMetadataProvider.cs b/src/Core/Services/MetadataProviders/SqlMetadataProvider.cs index 951b5984e4..cbd9f70298 100644 --- a/src/Core/Services/MetadataProviders/SqlMetadataProvider.cs +++ b/src/Core/Services/MetadataProviders/SqlMetadataProvider.cs @@ -1474,7 +1474,7 @@ private async Task PopulateSourceDefinitionAsync( && IsGraphQLReservedName(entity, columnName, graphQLEnabledGlobally: runtimeConfig.IsGraphQLEnabled)) { throw new DataApiBuilderException( - message: $"The column '{columnName}' violates GraphQL name restrictions.", + message: $"The column '{columnName}' from '{entityName}' violates GraphQL name restrictions.", statusCode: HttpStatusCode.ServiceUnavailable, subStatusCode: DataApiBuilderException.SubStatusCodes.ErrorInInitialization); } @@ -1584,7 +1584,8 @@ public static bool IsGraphQLReservedName(Entity entity, string databaseColumnNam } } - return IsIntrospectionField(databaseColumnName); + // Possible naming violations are if the field starts with '__' or if it contains whitespace characters. + return IsIntrospectionField(databaseColumnName) || IsGraphQLNameWhiteSpace(databaseColumnName); } } diff --git a/src/Service.GraphQLBuilder/GraphQLNaming.cs b/src/Service.GraphQLBuilder/GraphQLNaming.cs index 7ac3cc6494..9403e4c7b4 100644 --- a/src/Service.GraphQLBuilder/GraphQLNaming.cs +++ b/src/Service.GraphQLBuilder/GraphQLNaming.cs @@ -28,6 +28,8 @@ public static class GraphQLNaming /// public const string INTROSPECTION_FIELD_PREFIX = "__"; + public const string INVALID_EMPTY_SPACE = " "; + public const string LINKING_OBJECT_PREFIX = "linkingObject"; public const string PK_QUERY_SUFFIX = "_by_pk"; @@ -96,6 +98,20 @@ public static bool IsIntrospectionField(string fieldName) return fieldName.StartsWith(INTROSPECTION_FIELD_PREFIX, StringComparison.Ordinal); } + /// + /// Per GraphQL specification: + /// A name can only start with a letter or an underscore, and can only + /// contain letters, numbers, and underscores. It is not able to contain whitespaces + /// This helper function identifies whether the provided name contains whitespaces. + /// + /// + /// Field name to evaluate + /// True/False + public static bool IsGraphQLNameWhiteSpace(string fieldName) + { + return fieldName.Contains(INVALID_EMPTY_SPACE, StringComparison.Ordinal); + } + /// /// Attempts to deserialize and get the SingularPlural GraphQL naming config /// of an Entity from the Runtime Configuration and return the singular name of the entity. diff --git a/src/Service.Tests/Configuration/ConfigurationTests.cs b/src/Service.Tests/Configuration/ConfigurationTests.cs index 8c60795125..02dfbcbd92 100644 --- a/src/Service.Tests/Configuration/ConfigurationTests.cs +++ b/src/Service.Tests/Configuration/ConfigurationTests.cs @@ -5651,7 +5651,7 @@ public async Task TestAutoentitiesWithSameObjectDifferentSchemas() "PublisherAutoEntity", new Autoentity( Patterns: new AutoentityPatterns( Include: null, - Exclude: new[] { "dbo.GQLmappings", "dbo.graphql_incompatible", "dbo.brokers" }, + Exclude: new[] { "dbo.GQLmappings", "dbo.brokers" }, Name: null ), Template: new AutoentityTemplate(