Browse Source

Merge pull request #26123 from eypcnckr/fix/enum-datatype-attribute-adapter

Add an attribute adapter for EnumDataTypeAttribute
rel-10.7
Ma Liming 24 hours ago
committed by GitHub
parent
commit
5c7aaf147c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 5
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/DataAnnotations/AbpValidationAttributeAdapterProvider.cs
  2. 34
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/DataAnnotations/EnumDataTypeAttributeAdapter.cs
  3. 72
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/DataAnnotations/AbpValidationAttributeAdapterProvider_Tests.cs

5
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/DataAnnotations/AbpValidationAttributeAdapterProvider.cs

@ -33,6 +33,11 @@ public class AbpValidationAttributeAdapterProvider : IValidationAttributeAdapter
return new DynamicRangeAttributeAdapter((DynamicRangeAttribute)attribute, stringLocalizer);
}
if (type == typeof(EnumDataTypeAttribute))
{
return new EnumDataTypeAttributeAdapter((EnumDataTypeAttribute)attribute, stringLocalizer);
}
return _defaultAdapter.GetAttributeAdapter(attribute, stringLocalizer);
}
}

34
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/DataAnnotations/EnumDataTypeAttributeAdapter.cs

@ -0,0 +1,34 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc.DataAnnotations;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.Extensions.Localization;
namespace Volo.Abp.AspNetCore.Mvc.DataAnnotations;
public class EnumDataTypeAttributeAdapter : AttributeAdapterBase<EnumDataTypeAttribute>
{
public EnumDataTypeAttributeAdapter(
EnumDataTypeAttribute attribute,
IStringLocalizer? stringLocalizer)
: base(attribute, stringLocalizer)
{
}
public override void AddValidation(ClientModelValidationContext context)
{
Check.NotNull(context, nameof(context));
//There is no built-in client side validation rule for enum values.
//This adapter is used to localize the error message on the server side.
}
public override string GetErrorMessage(ModelValidationContextBase validationContext)
{
Check.NotNull(validationContext, nameof(validationContext));
return GetErrorMessage(
validationContext.ModelMetadata,
validationContext.ModelMetadata.GetDisplayName()
);
}
}

72
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/DataAnnotations/AbpValidationAttributeAdapterProvider_Tests.cs

@ -0,0 +1,72 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.DataAnnotations;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.Extensions.Localization;
using Shouldly;
using Xunit;
namespace Volo.Abp.AspNetCore.Mvc.DataAnnotations;
public class AbpValidationAttributeAdapterProvider_Tests
{
private readonly AbpValidationAttributeAdapterProvider _provider = new(new ValidationAttributeAdapterProvider());
[Fact]
public void Should_Return_An_Adapter_For_The_EnumDataTypeAttribute()
{
//ASP.NET Core does not provide an adapter for the EnumDataTypeAttribute.
new ValidationAttributeAdapterProvider()
.GetAttributeAdapter(new EnumDataTypeAttribute(typeof(MyEnum)), null)
.ShouldBeNull();
_provider.GetAttributeAdapter(new EnumDataTypeAttribute(typeof(MyEnum)), null)
.ShouldBeOfType<EnumDataTypeAttributeAdapter>();
}
[Fact]
public void Should_Localize_The_Error_Message_Of_The_EnumDataTypeAttribute()
{
var attribute = new EnumDataTypeAttribute(typeof(MyEnum)) { ErrorMessage = "MyEnumIsInvalid" };
var adapter = _provider.GetAttributeAdapter(attribute, new TestStringLocalizer())!;
adapter.GetErrorMessage(CreateValidationContext()).ShouldBe("Localized:MyEnumIsInvalid");
}
private static ModelValidationContextBase CreateValidationContext()
{
var metadataProvider = new EmptyModelMetadataProvider();
return new ClientModelValidationContext(
new ActionContext(),
metadataProvider.GetMetadataForProperty(typeof(MyModel), nameof(MyModel.Value)),
metadataProvider,
new Dictionary<string, string>()
);
}
public enum MyEnum
{
Value1 = 1
}
public class MyModel
{
public MyEnum Value { get; set; }
}
private class TestStringLocalizer : IStringLocalizer
{
public LocalizedString this[string name] => new(name, "Localized:" + name);
public LocalizedString this[string name, params object[] arguments] => new(name, "Localized:" + name);
public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures)
{
return new List<LocalizedString>();
}
}
}
Loading…
Cancel
Save