@@ -215,41 +215,65 @@ private string FormatErrorMessage(string errorMessage)
215215 return errorMessage ;
216216 }
217217
218- // Common pattern : "The {PropertyName} field is required."
219- const string pattern = "The " ;
220- const string fieldPattern = " field " ;
218+ // Pattern 1 : "The {PropertyName} field is required."
219+ const string pattern1Start = "The " ;
220+ const string pattern1Middle = " field " ;
221221
222- int startIndex = errorMessage . IndexOf ( pattern , StringComparison . Ordinal ) ;
223- if ( startIndex != 0 )
224- {
225- return errorMessage ; // Does not start with "The "
226- }
222+ // Pattern 2: "The field {PropertyName} must be between X and Y."
223+ const string pattern2 = "The field " ;
227224
228- int endIndex = errorMessage . IndexOf ( fieldPattern , pattern . Length , StringComparison . Ordinal ) ;
229- if ( endIndex <= pattern . Length )
225+ // Try Pattern 1 first
226+ if ( errorMessage . StartsWith ( pattern1Start , StringComparison . Ordinal ) )
230227 {
231- return errorMessage ; // Does not contain " field " or it's too early
228+ int endIndex = errorMessage . IndexOf ( pattern1Middle , pattern1Start . Length , StringComparison . Ordinal ) ;
229+ if ( endIndex > pattern1Start . Length )
230+ {
231+ // Extract the property name between "The " and " field "
232+ ReadOnlySpan < char > messageSpan = errorMessage . AsSpan ( ) ;
233+ ReadOnlySpan < char > propertyNameSpan = messageSpan . Slice ( pattern1Start . Length , endIndex - pattern1Start . Length ) ;
234+ string propertyName = propertyNameSpan . ToString ( ) ;
235+
236+ if ( ! string . IsNullOrWhiteSpace ( propertyName ) )
237+ {
238+ // Format the property name with the naming policy
239+ string formattedPropertyName = SerializerOptions . PropertyNamingPolicy . ConvertName ( propertyName ) ;
240+
241+ // Construct the new error message by combining parts
242+ return string . Concat (
243+ pattern1Start ,
244+ formattedPropertyName ,
245+ messageSpan . Slice ( endIndex ) . ToString ( )
246+ ) ;
247+ }
248+ }
232249 }
233-
234- // Extract the property name between "The " and " field "
235- // Use ReadOnlySpan<char> for better performance
236- ReadOnlySpan < char > messageSpan = errorMessage . AsSpan ( ) ;
237- ReadOnlySpan < char > propertyNameSpan = messageSpan . Slice ( pattern . Length , endIndex - pattern . Length ) ;
238- string propertyName = propertyNameSpan . ToString ( ) ;
239-
240- if ( string . IsNullOrWhiteSpace ( propertyName ) )
250+ // Try Pattern 2
251+ else if ( errorMessage . StartsWith ( pattern2 , StringComparison . Ordinal ) )
241252 {
242- return errorMessage ;
253+ // Find the word after "The field " and before " must"
254+ const string pattern2End = " must" ;
255+ int startPos = pattern2 . Length ;
256+ int endPos = errorMessage . IndexOf ( pattern2End , startPos , StringComparison . Ordinal ) ;
257+
258+ if ( endPos > startPos )
259+ {
260+ string propertyName = errorMessage . Substring ( startPos , endPos - startPos ) ;
261+ if ( ! string . IsNullOrWhiteSpace ( propertyName ) )
262+ {
263+ // Format the property name with the naming policy
264+ string formattedPropertyName = SerializerOptions . PropertyNamingPolicy . ConvertName ( propertyName ) ;
265+
266+ // Reconstruct the message
267+ ReadOnlySpan < char > errorSpan = errorMessage . AsSpan ( ) ;
268+ return string . Concat (
269+ pattern2 ,
270+ formattedPropertyName ,
271+ errorSpan . Slice ( endPos ) ) ;
272+ }
273+ }
243274 }
244275
245- // Format the property name with the naming policy
246- string formattedPropertyName = SerializerOptions . PropertyNamingPolicy . ConvertName ( propertyName ) ;
247-
248- // Construct the new error message by combining parts
249- return string . Concat (
250- pattern ,
251- formattedPropertyName ,
252- messageSpan . Slice ( endIndex ) . ToString ( )
253- ) ;
276+ // Return the original message if no patterns matched or formatting failed
277+ return errorMessage ;
254278 }
255279}
0 commit comments