diff --git a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml
index e77304762..dd4e87789 100644
--- a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml
+++ b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml
@@ -7668,7 +7668,7 @@
- Looks up a localized string similar to The template string '{0}' of '{1}' is not a valid template literal. And a template literal should wrapper with '{' and '}'..
+ Looks up a localized string similar to The template string '{0}' of '{1}' is not a valid template literal. And a template literal should wrapper with '{{' and '}}'..
diff --git a/src/Microsoft.AspNetCore.OData/Properties/SRResources.Designer.cs b/src/Microsoft.AspNetCore.OData/Properties/SRResources.Designer.cs
index 822469127..c7474590a 100644
--- a/src/Microsoft.AspNetCore.OData/Properties/SRResources.Designer.cs
+++ b/src/Microsoft.AspNetCore.OData/Properties/SRResources.Designer.cs
@@ -889,7 +889,7 @@ internal static string InvalidSegmentInSelectExpandPath {
}
///
- /// Looks up a localized string similar to The template string '{0}' of '{1}' is not a valid template literal. And a template literal should wrapper with '{' and '}'..
+ /// Looks up a localized string similar to The template string '{0}' of '{1}' is not a valid template literal. And a template literal should wrapper with '{{' and '}}'..
///
internal static string InvalidTemplateLiteral {
get {
@@ -1841,7 +1841,7 @@ internal static string TypeMustBeRelated {
return ResourceManager.GetString("TypeMustBeRelated", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to '{0}' is not a resource set type. Only resource set are supported..
///
@@ -1850,7 +1850,7 @@ internal static string TypeMustBeResourceSet {
return ResourceManager.GetString("TypeMustBeResourceSet", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to The type '{0}' does not implement '{1}' interface..
///
@@ -1859,7 +1859,7 @@ internal static string TypeMustImplementInterface {
return ResourceManager.GetString("TypeMustImplementInterface", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to The type '{0}' does not inherit from '{1}'..
///
@@ -1868,7 +1868,7 @@ internal static string TypeMustInheritFromType {
return ResourceManager.GetString("TypeMustInheritFromType", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to The type '{0}' of dynamic property '{1}' is not supported..
///
diff --git a/src/Microsoft.AspNetCore.OData/Properties/SRResources.resx b/src/Microsoft.AspNetCore.OData/Properties/SRResources.resx
index e41cf3321..df3e78414 100644
--- a/src/Microsoft.AspNetCore.OData/Properties/SRResources.resx
+++ b/src/Microsoft.AspNetCore.OData/Properties/SRResources.resx
@@ -667,7 +667,7 @@
Cannot Get the Enum Clr member using '{0}'.
- The template string '{0}' of '{1}' is not a valid template literal. And a template literal should wrapper with '{' and '}'.
+ The template string '{0}' of '{1}' is not a valid template literal. And a template literal should wrapper with '{{' and '}}'.
Missing the parameter alias '{0}' in the request query string.
diff --git a/test/Microsoft.AspNetCore.OData.Tests/Resources/SRResourcesTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Resources/SRResourcesTests.cs
new file mode 100644
index 000000000..9af61d278
--- /dev/null
+++ b/test/Microsoft.AspNetCore.OData.Tests/Resources/SRResourcesTests.cs
@@ -0,0 +1,251 @@
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) .NET Foundation and Contributors. All rights reserved.
+// See License.txt in the project root for license information.
+//
+//------------------------------------------------------------------------------
+
+using System.Linq;
+using System.Text.RegularExpressions;
+using Xunit;
+
+namespace Microsoft.AspNetCore.OData.Tests.Resources;
+
+public class SRResourcesTests
+{
+ [Theory]
+ [InlineData("ActionContextMustHaveDescriptor", new object[] { })]
+ [InlineData("ActionDescriptorNotControllerActionDescriptor", new object[] { })]
+ [InlineData("ActionExecutedContextMustHaveRequest", new object[] { })]
+ [InlineData("ActionNotBoundToCollectionOfEntity", new object[] { "arg1" })]
+ [InlineData("ActionNotBoundToEntity", new object[] { "arg1" })]
+ [InlineData("AggregateKindNotSupported", new object[] { "arg1" })]
+ [InlineData("AggregationMethodNotSupported", new object[] { "arg1" })]
+ [InlineData("AggregationNotSupportedForType", new object[] { "arg1", "arg2", "arg3" })]
+ [InlineData("AmbiguousNavigationSourceNameFound", new object[] { "arg1" })]
+ [InlineData("AmbiguousPropertyNameFound", new object[] { "arg1" })]
+ [InlineData("AmbiguousTypeNameFound", new object[] { "arg1" })]
+ [InlineData("ApplyQueryOptionNotSupportedForLinq2SQL", new object[] { })]
+ [InlineData("ApplyToOnUntypedQueryOption", new object[] { "arg1" })]
+ [InlineData("ArgumentMustBeGreaterThanOrEqualTo", new object[] { "arg1" })]
+ [InlineData("ArgumentMustBeLessThanOrEqualTo", new object[] { "arg1" })]
+ [InlineData("ArgumentMustBeOfType", new object[] { "arg1" })]
+ [InlineData("ArgumentNullOrEmpty", new object[] { "arg1" })]
+ [InlineData("BatchRequestInvalidMediaType", new object[] { "arg1", "arg2" })]
+ [InlineData("BatchRequestMissingBody", new object[] { })]
+ [InlineData("BatchRequestMissingBoundary", new object[] { })]
+ [InlineData("BatchRequestMissingContentType", new object[] { })]
+ [InlineData("BinaryOperatorNotSupported", new object[] { "arg1", "arg2", "arg3" })]
+ [InlineData("CannotAddToNullCollection", new object[] { "arg1", "arg2" })]
+ [InlineData("CannotApplyETagOfT", new object[] { "arg1", "arg2", "arg3", "arg4" })]
+ [InlineData("CannotApplyODataQueryOptionsOfT", new object[] { "arg1", "arg2", "arg3", "arg4" })]
+ [InlineData("CannotCastFilter", new object[] { "arg1", "arg2" })]
+ [InlineData("CannotDeserializeUnknownProperty", new object[] { "arg1", "arg2" })]
+ [InlineData("CannotFindKeyInEntityType", new object[] { "arg1", "arg2" })]
+ [InlineData("CannotFindParameterInOperation", new object[] { "arg1", "arg2" })]
+ [InlineData("CannotGetEnumClrMember", new object[] { "arg1" })]
+ [InlineData("CannotInstantiateAbstractResourceType", new object[] { "arg1" })]
+ [InlineData("CannotParseQueryRequestPayload", new object[] { })]
+ [InlineData("CannotPatchNavigationProperties", new object[] { "arg1", "arg2" })]
+ [InlineData("CannotProcessPrefixTemplate", new object[] { "arg1" })]
+ [InlineData("CannotSerializerNull", new object[] { "arg1" })]
+ [InlineData("CannotSetDynamicPropertyDictionary", new object[] { "arg1", "arg2" })]
+ [InlineData("CannotWriteType", new object[] { "arg1", "arg2" })]
+ [InlineData("ClrTypeNotInModel", new object[] { "arg1" })]
+ [InlineData("CollectionParameterShouldHaveAddMethod", new object[] { "arg1", "arg2" })]
+ [InlineData("CollectionShouldHaveAddMethod", new object[] { "arg1", "arg2", "arg3" })]
+ [InlineData("CollectionShouldHaveClearMethod", new object[] { "arg1", "arg2", "arg3" })]
+ [InlineData("ConvertToEnumFailed", new object[] { "arg1", "arg2" })]
+ [InlineData("CreateODataValueNotSupported", new object[] { "arg1" })]
+ [InlineData("CustomQueryOptionNotSupportedWithDollarSign", new object[] { "arg1" })]
+ [InlineData("DeltaEntityTypeNotAssignable", new object[] { "arg1", "arg2" })]
+ [InlineData("DeltaNestedResourceNameNotFound", new object[] { "arg1", "arg2" })]
+ [InlineData("DeltaTypeMismatch", new object[] { "arg1", "arg2" })]
+ [InlineData("DeserializerDoesNotSupportRead", new object[] { "arg1" })]
+ [InlineData("DoesNotSupportReadInLine", new object[] { "arg1" })]
+ [InlineData("DuplicateDynamicPropertyNameFound", new object[] { "arg1", "arg2" })]
+ [InlineData("DynamicPropertyCannotBeSerialized", new object[] { "arg1", "arg2" })]
+ [InlineData("DynamicPropertyNameAlreadyUsedAsDeclaredPropertyName", new object[] { "arg1", "arg2" })]
+ [InlineData("DynamicResourceSetTypeNameIsRequired", new object[] { "arg1" })]
+ [InlineData("EditLinkNullForLocationHeader", new object[] { "arg1" })]
+ [InlineData("EdmComplexObjectNullRef", new object[] { "arg1", "arg2" })]
+ [InlineData("EdmObjectNull", new object[] { "arg1" })]
+ [InlineData("EdmTypeCannotBeNull", new object[] { "arg1", "arg2" })]
+ [InlineData("EdmTypeNotSupported", new object[] { "arg1" })]
+ [InlineData("ElementClrTypeNull", new object[] { "arg1" })]
+ [InlineData("EmptyKeyTemplate", new object[] { "arg1", "arg2" })]
+ [InlineData("EmptyParameterAlias", new object[] { "arg1", "arg2" })]
+ [InlineData("EmptyPathTemplate", new object[] { "arg1" })]
+ [InlineData("EntityReferenceMustHasKeySegment", new object[] { "arg1" })]
+ [InlineData("EntityTypeMismatch", new object[] { "arg1", "arg2" })]
+ [InlineData("ErrorTypeMustBeODataErrorOrHttpError", new object[] { "arg1" })]
+ [InlineData("ETagNotWellFormed", new object[] { })]
+ [InlineData("ExpandFilterExpressionNotLambdaExpression", new object[] { "arg1", "arg2" })]
+ [InlineData("ExpressionLexer_UnbalancedBracketExpression", new object[] { "arg1", "arg2" })]
+ [InlineData("ExpressionLexerSyntaxError", new object[] { "arg1", "arg2" })]
+ [InlineData("ExpressionLexerUnterminatedStringLiteral", new object[] { "arg1", "arg2" })]
+ [InlineData("FailedToBuildEdmModelBecauseReturnTypeIsNull", new object[] { "arg1", "arg2" })]
+ [InlineData("FailedToRetrieveTypeToBuildEdmModel", new object[] { "arg1", "arg2", "arg3" })]
+ [InlineData("FormatterReadIsNotSupportedForType", new object[] { "arg1", "arg2" })]
+ [InlineData("FunctionNotBoundToCollectionOfEntity", new object[] { "arg1" })]
+ [InlineData("FunctionNotBoundToEntity", new object[] { "arg1" })]
+ [InlineData("FunctionNotSupportedOnEnum", new object[] { "arg1" })]
+ [InlineData("GetOnlyCollectionCannotBeArray", new object[] { "arg1", "arg2" })]
+ [InlineData("IdLinkNullForEntityIdHeader", new object[] { "arg1" })]
+ [InlineData("InfiniteParameterAlias", new object[] { "arg1" })]
+ [InlineData("InputCastTypeKindNotMatch", new object[] { "arg1", "arg2" })]
+ [InlineData("InputKeyNotMatchEntityTypeKey", new object[] { "arg1", "arg2", "arg3" })]
+ [InlineData("InvalidAttributeRoutingTemplateSegment", new object[] { "arg1" })]
+ [InlineData("InvalidBatchReaderState", new object[] { "arg1", "arg2" })]
+ [InlineData("InvalidExpansionDepthValue", new object[] { "arg1", "arg2" })]
+ [InlineData("InvalidKeyInUriFound", new object[] { "arg1", "arg2" })]
+ [InlineData("InvalidLastSegmentInSelectExpandPath", new object[] { "arg1" })]
+ [InlineData("InvalidODataRouteOnAction", new object[] { "arg1", "arg2", "arg3", "arg4" })]
+ [InlineData("InvalidODataUntypedValue", new object[] { "arg1" })]
+ [InlineData("InvalidParameterValueInUriFound", new object[] { "arg1", "arg2" })]
+ [InlineData("InvalidPropertyMapper", new object[] { "arg1", "arg2" })]
+ [InlineData("InvalidPropertyMapping", new object[] { "arg1" })]
+ [InlineData("InvalidSegmentInSelectExpandPath", new object[] { "arg1" })]
+ [InlineData("InvalidTemplateLiteral", new object[] { "arg1", "arg2" })]
+ [InlineData("JsonConverterDoesnotSupportRead", new object[] { "arg1" })]
+ [InlineData("KeyTemplateMustBeInCurlyBraces", new object[] { "arg1", "arg2" })]
+ [InlineData("KeyValueCannotBeNull", new object[] { "arg1", "arg2" })]
+ [InlineData("MappingDoesNotContainResourceType", new object[] { "arg1" })]
+ [InlineData("MaxAnyAllExpressionLimitExceeded", new object[] { "arg1", "arg2" })]
+ [InlineData("MaxExpandDepthExceeded", new object[] { "arg1", "arg2" })]
+ [InlineData("MaxNodeLimitExceeded", new object[] { "arg1", "arg2" })]
+ [InlineData("MissingNonODataContainer", new object[] { })]
+ [InlineData("MissingNonStandardTypeSupportFor", new object[] { "arg1" })]
+ [InlineData("MissingODataContainer", new object[] { "arg1" })]
+ [InlineData("MissingODataServices", new object[] { "arg1" })]
+ [InlineData("MissingParameterAlias", new object[] { "arg1" })]
+ [InlineData("MissingRequiredParameterInOperation", new object[] { "arg1", "arg2" })]
+ [InlineData("ModelBinderUtil_ModelMetadataCannotBeNull", new object[] { })]
+ [InlineData("ModelBinderUtil_ValueCannotBeEnum", new object[] { "arg1", "arg2" })]
+ [InlineData("ModelBindingContextMustHaveRequest", new object[] { })]
+ [InlineData("ModelMissingFromReadContext", new object[] { })]
+ [InlineData("ModelPrefixAlreadyUsed", new object[] { "arg1" })]
+ [InlineData("MultipleActionImportFound", new object[] { "arg1" })]
+ [InlineData("MultipleMatchingClrTypesForEdmType", new object[] { "arg1", "arg2" })]
+ [InlineData("MultipleSingleLiteralNotAllowed", new object[] { "arg1" })]
+ [InlineData("NavigationSourceMissingDuringDeserialization", new object[] { })]
+ [InlineData("NavigationSourceMissingDuringSerialization", new object[] { })]
+ [InlineData("NestedCollectionsNotSupported", new object[] { "arg1" })]
+ [InlineData("NestedPropertyNotfound", new object[] { "arg1", "arg2" })]
+ [InlineData("NonSelectExpandOnSingleEntity", new object[] { })]
+ [InlineData("NotAllowedArithmeticOperator", new object[] { "arg1", "arg2" })]
+ [InlineData("NotAllowedFunction", new object[] { "arg1", "arg2" })]
+ [InlineData("NotAllowedLogicalOperator", new object[] { "arg1", "arg2" })]
+ [InlineData("NotAllowedOrderByProperty", new object[] { "arg1", "arg2" })]
+ [InlineData("NotAllowedQueryOption", new object[] { "arg1", "arg2" })]
+ [InlineData("NotCountableEntitySetUsedForCount", new object[] { "arg1" })]
+ [InlineData("NotCountablePropertyUsedForCount", new object[] { "arg1" })]
+ [InlineData("NotExpandablePropertyUsedInExpand", new object[] { "arg1" })]
+ [InlineData("NotFilterablePropertyUsedInFilter", new object[] { "arg1" })]
+ [InlineData("NotNavigablePropertyUsedInNavigation", new object[] { "arg1" })]
+ [InlineData("NotSelectablePropertyUsedInSelect", new object[] { "arg1" })]
+ [InlineData("NotSortablePropertyUsedInOrderBy", new object[] { "arg1" })]
+ [InlineData("NotSupportedChildTransformationKind", new object[] { "arg1", "arg2" })]
+ [InlineData("NotSupportedTransformationKind", new object[] { "arg1" })]
+ [InlineData("NullContainer", new object[] { })]
+ [InlineData("NullContainerBuilder", new object[] { })]
+ [InlineData("NullElementInCollection", new object[] { })]
+ [InlineData("ODataFunctionNotSupported", new object[] { "arg1" })]
+ [InlineData("ODataPathMissing", new object[] { })]
+ [InlineData("OnlySingleValueNodeSupported", new object[] { })]
+ [InlineData("OperationIsNotBound", new object[] { "arg1", "arg2" })]
+ [InlineData("OperationMustBeUniqueInEntitySetContainer", new object[] { "arg1" })]
+ [InlineData("OrderByClauseInvalid", new object[] { "arg1", "arg2" })]
+ [InlineData("OrderByClauseNotSupported", new object[] { })]
+ [InlineData("OrderByDuplicateIt", new object[] { })]
+ [InlineData("OrderByDuplicateProperty", new object[] { "arg1" })]
+ [InlineData("OrderByNodeCountExceeded", new object[] { "arg1" })]
+ [InlineData("ParameterTemplateMustBeInCurlyBraces", new object[] { "arg1", "arg2" })]
+ [InlineData("ParameterTypeIsNotCollection", new object[] { "arg1", "arg2" })]
+ [InlineData("PropertyCannotBeConverted", new object[] { "arg1" })]
+ [InlineData("PropertyIsNotCollection", new object[] { "arg1", "arg2", "arg3" })]
+ [InlineData("PropertyMustBeBoolean", new object[] { })]
+ [InlineData("PropertyMustBeDateTimeOffsetOrDate", new object[] { })]
+ [InlineData("PropertyMustBeEnum", new object[] { "arg1", "arg2" })]
+ [InlineData("PropertyMustBeSet", new object[] { "arg1" })]
+ [InlineData("PropertyMustBeSetWhenAnotherPropertyIsSet", new object[] { "arg1", "arg2" })]
+ [InlineData("PropertyMustBeString", new object[] { })]
+ [InlineData("PropertyMustBeStringLengthOne", new object[] { })]
+ [InlineData("PropertyMustBeStringMaxLengthOne", new object[] { })]
+ [InlineData("PropertyMustBeTimeOfDay", new object[] { })]
+ [InlineData("PropertyMustHavePublicGetterAndSetter", new object[] { })]
+ [InlineData("PropertyNotFound", new object[] { "arg1", "arg2" })]
+ [InlineData("PropertyNotFoundOnPathExpression", new object[] { "arg1", "arg2" })]
+ [InlineData("PropertyOrPathWasRemovedFromContext", new object[] { "arg1" })]
+ [InlineData("PropertyTypeOverflow", new object[] { "arg1" })]
+ [InlineData("PropertyUnrecognizedFormat", new object[] { "arg1" })]
+ [InlineData("QueryCannotBeEmpty", new object[] { "arg1" })]
+ [InlineData("QueryGetModelMustNotReturnNull", new object[] { })]
+ [InlineData("QueryNodeBindingNotSupported", new object[] { "arg1", "arg2" })]
+ [InlineData("QueryNodeValidationNotSupported", new object[] { "arg1", "arg2" })]
+ [InlineData("QueryParameterNotSupported", new object[] { "arg1" })]
+ [InlineData("ReadFromStreamAsyncMustHaveRequest", new object[] { })]
+ [InlineData("ReferenceNavigationPropertyExpandFilterVisitorUnexpectedParameter", new object[] { "arg1" })]
+ [InlineData("RequestMustHaveModel", new object[] { })]
+ [InlineData("RequestNotActionInvocation", new object[] { "arg1" })]
+ [InlineData("RequiredParametersNotSubsetOfFunctionParameters", new object[] { "arg1", "arg2" })]
+ [InlineData("ResourceTypeNotInModel", new object[] { "arg1" })]
+ [InlineData("RootElementNameMissing", new object[] { "arg1" })]
+ [InlineData("RouteOptionDisabledKeySegment", new object[] { })]
+ [InlineData("RouteOptionDisabledOperationSegment", new object[] { })]
+ [InlineData("RouteServicesAlreadyExist", new object[] { })]
+ [InlineData("SegmentShouldBeKind", new object[] { "arg1", "arg2" })]
+ [InlineData("SelectExpandEmptyOrNull", new object[] { })]
+ [InlineData("SelectExpandEmptyOrWhitespace", new object[] { })]
+ [InlineData("SelectionTypeNotSupported", new object[] { "arg1" })]
+ [InlineData("SelectNonStructured", new object[] { "arg1" })]
+ [InlineData("ShouldHaveNavigationPropertyInNavigationExpandPath", new object[] { })]
+ [InlineData("SingleResultHasMoreThanOneEntity", new object[] { "arg1", "arg2", "arg3" })]
+ [InlineData("SkipTokenNotSupportedOrderByExpression", new object[] { "arg1" })]
+ [InlineData("SkipTokenParseError", new object[] { "arg1" })]
+ [InlineData("SkipTokenProcessingError", new object[] { })]
+ [InlineData("SkipTopLimitExceeded", new object[] { "arg1", "arg2", "arg3" })]
+ [InlineData("TargetKindNotImplemented", new object[] { "arg1", "arg2" })]
+ [InlineData("TypeCannotBeDeserialized", new object[] { "arg1" })]
+ [InlineData("TypeCannotBeSerialized", new object[] { "arg1" })]
+ [InlineData("TypeMustBeEntity", new object[] { "arg1" })]
+ [InlineData("TypeMustBeEnumOrNullableEnum", new object[] { "arg1" })]
+ [InlineData("TypeMustBeOpenType", new object[] { "arg1" })]
+ [InlineData("TypeMustBeRelated", new object[] { "arg1", "arg2" })]
+ [InlineData("TypeMustBeResourceSet", new object[] { "arg1" })]
+ [InlineData("TypeMustImplementInterface", new object[] { "arg1", "arg2" })]
+ [InlineData("TypeMustInheritFromType", new object[] { "arg1", "arg2" })]
+ [InlineData("TypeOfDynamicPropertyNotSupported", new object[] { "arg1", "arg2" })]
+ [InlineData("UnableToDetermineBaseUrl", new object[] { })]
+ [InlineData("UnableToDetermineMetadataUrl", new object[] { })]
+ [InlineData("UnableToIdentifyUniqueProperty", new object[] { "arg1" })]
+ [InlineData("UnaryNodeValidationNotSupported", new object[] { "arg1", "arg2" })]
+ [InlineData("UnexpectedElementType", new object[] { "arg1", "arg2", "arg3" })]
+ [InlineData("UnsupportedEdmType", new object[] { "arg1", "arg2" })]
+ [InlineData("UnsupportedEdmTypeKind", new object[] { "arg1" })]
+ [InlineData("UriFunctionClrBinderAlreadyBound", new object[] { "arg1" })]
+ [InlineData("UriQueryStringInvalid", new object[] { "arg1" })]
+ [InlineData("ValueIsInvalid", new object[] { "arg1", "arg2" })]
+ [InlineData("WriteObjectInlineNotSupported", new object[] { "arg1" })]
+ [InlineData("WriteObjectNotSupported", new object[] { "arg1" })]
+ [InlineData("WriteToResponseAsyncMustHaveRequest", new object[] { })]
+ public void ResourceKey_ShouldFormatWithoutException(string resourceKey, object[] formatArgs)
+ {
+ // Arrange
+ var resourceValue = SRResources.ResourceManager.GetString(resourceKey, SRResources.Culture);
+ Assert.NotNull(resourceValue); // Ensure the resource exists
+
+ // Act & Assert
+ var exception = Record.Exception(() => Error.Format(resourceValue, formatArgs));
+ Assert.Null(exception); // Ensure no Exception is thrown
+
+ // Match numbers of arguments required in the resource string and validate against formatArgs
+ var matches = Regex.Matches(resourceValue, @"\{\d+\}").Select(m => m.Value).Distinct();
+ Assert.Equal(matches.Count(), formatArgs.Length);
+
+ var formattedValue = Error.Format(resourceValue, formatArgs);
+ Assert.NotNull(formattedValue);
+
+ Assert.Equal(formattedValue, string.Format(resourceValue, formatArgs));
+ }
+}