Skip to content

Commit

Permalink
Merge pull request #1869 from riganti/Feature/ValidationContextHasSer…
Browse files Browse the repository at this point in the history
…viceProvider

Initialized service provider in validation context.
  • Loading branch information
exyi authored Oct 10, 2024
2 parents 0df5117 + 74dc13f commit d2816a9
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ private IEnumerable<ViewModelValidationError> ValidateViewModel(object? viewMode

// validate all properties on the object
var map = viewModelSerializationMapper.GetMap(viewModel.GetType());
var dotvvmConfiguration = (DotvvmConfiguration)validationItems[typeof(DotvvmConfiguration)]!;

foreach (var property in map.Properties.Where(p => p.TransferToServer))
{
var value = property.PropertyInfo.GetValue(viewModel);
Expand All @@ -74,6 +76,7 @@ private IEnumerable<ViewModelValidationError> ValidateViewModel(object? viewMode
if (property.ValidationRules.Any())
{
var context = new ValidationContext(viewModel, validationItems) { MemberName = property.Name };
context.InitializeServiceProvider(dotvvmConfiguration.ServiceProvider.GetService);

foreach (var rule in property.ValidationRules)
{
Expand Down Expand Up @@ -103,8 +106,11 @@ private IEnumerable<ViewModelValidationError> ValidateViewModel(object? viewMode

if (viewModel is IValidatableObject)
{
foreach (var error in ((IValidatableObject)viewModel).Validate(
new ValidationContext(viewModel, validationItems)))
var validationContext = new ValidationContext(viewModel, validationItems);
validationContext.InitializeServiceProvider(dotvvmConfiguration.ServiceProvider.GetService);
var errors = ((IValidatableObject)viewModel).Validate(validationContext);

foreach (var error in errors)
{
var paths = new List<string>();
if (error.MemberNames != null)
Expand All @@ -114,6 +120,7 @@ private IEnumerable<ViewModelValidationError> ValidateViewModel(object? viewMode
paths.Add(memberPath);
}
}

if (!paths.Any())
{
paths.Add(string.Empty);
Expand Down
39 changes: 37 additions & 2 deletions src/Tests/ViewModel/ViewModelValidatorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,22 @@ public void ViewModelValidator_AttemptToPassOldPaths(string path)
}


[TestMethod]
public void ViewModelValidator_ServiceProvider()
{
var testViewModel = new TestViewModel8();
var validator = CreateValidator();
var expander = CreateErrorPathExpander();
var modelState = new ModelState { ValidationTarget = testViewModel };

var errors = validator.ValidateViewModel(testViewModel).OrderBy(n => n.PropertyPath);
modelState.ErrorsInternal.AddRange(errors);
expander.Expand(modelState, testViewModel);
var results = modelState.Errors.OrderBy(n => n.PropertyPath).ToList();

Assert.AreEqual(0, results.Count);
}

public class TestViewModel : DotvvmViewModelBase
{
[Required]
Expand Down Expand Up @@ -497,7 +513,7 @@ protected override ValidationResult IsValid(object value, ValidationContext vali
var entity = (TestViewModel4Child)validationContext.ObjectInstance;
if (entity.IsChecked && string.IsNullOrEmpty(entity.ConditionalRequired))
{
return new ValidationResult("Value is required when the field is checked!", new[] { validationContext.MemberName });
return new ValidationResult("Value is required when the field is checked!", new[] { validationContext.MemberName });
}

return base.IsValid(value, validationContext);
Expand Down Expand Up @@ -542,6 +558,25 @@ public IEnumerable<ValidationResult> Validate(ValidationContext validationContex
}
}
}
}


public class TestViewModel8
{
[ServiceProviderTest]
public int? Id { get; set; }

public class ServiceProviderTestAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (validationContext.GetService<IViewModelValidator>() == null)
{
return new ValidationResult("Service provider is not available");
}

return ValidationResult.Success;
}
}
}
}
}

0 comments on commit d2816a9

Please sign in to comment.