Skip to content

Commit acea848

Browse files
committed
Added support for HashSet collections in complex models. Fixes "Could not find indexer on object of type HashSet`1"
1 parent e3716a4 commit acea848

1 file changed

Lines changed: 11 additions & 15 deletions

File tree

vNext.BlazorComponents.FluentValidation/FluentValidationValidator.cs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ protected virtual async Task<ValidationResult> ValidateModel(ValidationMessageSt
136136
}
137137
catch (InvalidOperationException ex)
138138
{
139-
ServiceProvider.GetService<ILogger<FluentValidationValidator>>()?.LogError(ex, $"An error occured while parsing ValidationFailure(PropertyName={failure.PropertyName})");
140-
}
139+
ServiceProvider.GetService<ILogger<FluentValidationValidator>>()?.LogError(ex, $"An error occured while parsing ValidationFailure(PropertyName={failure.PropertyName})");
140+
}
141141
}
142142

143143
EditContext.NotifyValidationStateChanged();
@@ -152,7 +152,7 @@ protected virtual async Task<ValidationResult> ValidateModel(ValidationMessageSt
152152
EditContext.Properties[EditContextExtensions.PROPERTY_VALIDATEASYNCTASK] = Task.FromResult(emptyValidationResult);
153153
}
154154
return emptyValidationResult;
155-
}
155+
}
156156
}
157157

158158
protected virtual async Task<ValidationResult> ValidateField(ValidationMessageStore messages, FieldIdentifier fieldIdentifier, bool updateValidationState)
@@ -234,7 +234,9 @@ protected static FieldIdentifier ToFieldIdentifier(EditContext editContext, stri
234234
// It's an indexer
235235
// This code assumes C# conventions (one indexer named Item with one param)
236236
nextToken = nextToken.Substring(0, nextToken.Length - 1);
237-
var prop = obj.GetType().GetProperty("Item");
237+
238+
var prop = obj.GetType().GetProperties().Where(e => e.Name == "Item" && e.GetIndexParameters().Length == 1).FirstOrDefault()
239+
?? obj.GetType().GetInterfaces().FirstOrDefault(e => e.IsGenericType && e.GetGenericTypeDefinition() == typeof(IReadOnlyList<>) || e.GetGenericTypeDefinition() == typeof(IList<>))?.GetProperty("Item"); //e.g. arrays
238240

239241
if (prop is not null)
240242
{
@@ -243,19 +245,13 @@ protected static FieldIdentifier ToFieldIdentifier(EditContext editContext, stri
243245
var indexerValue = Convert.ChangeType(nextToken, indexerType);
244246
newObj = prop.GetValue(obj, new object[] { indexerValue });
245247
}
248+
else if (obj is IEnumerable<object> objEnumerable && int.TryParse(nextToken, out int indexerValue)) //e.g. hashset
249+
{
250+
newObj = objEnumerable.ElementAt(indexerValue);
251+
}
246252
else
247253
{
248-
// If there is no Item property
249-
// Try to cast the object to array
250-
if (obj is object[] array)
251-
{
252-
var indexerValue = Convert.ToInt32(nextToken);
253-
newObj = array[indexerValue];
254-
}
255-
else
256-
{
257-
throw new InvalidOperationException($"Could not find indexer on object of type {obj.GetType().FullName}.");
258-
}
254+
throw new InvalidOperationException($"Could not find indexer on object of type {obj.GetType().FullName}.");
259255
}
260256
}
261257
else

0 commit comments

Comments
 (0)