简体   繁体   中英

Blazor WebAssembly Client DataAnnotations Localization

Asp.net core server side localization is well documented and working for me. But how do you localize DataAnnotations on DTO models on the client side of Blazor webassembly?

On server side I've added the code below and DataAnnotations are localized. Everything is working as expected.

...
services
.AddRazorPages()              .AddViewLocalization(Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.Suffix)
                .AddDataAnnotationsLocalization(
                    options =>
                    {
                        options.DataAnnotationLocalizerProvider = (type, factory) =>
                        {
                            return factory.Create(typeof(CommonStrings));
                        };

                    });
...

But how do I do the same thing on Blazor client side (webassembly)? For example I have this model which is on client side:

public class ApplicationUserDTO
    {
        public string Id { get; set; }

        [Required(ErrorMessage ="Field {0} is required")]
        [Display(Name ="First name")]
        public string FirstName { get; set; }

        [Required]
        [Display(Name = "Last name")]
        public string LastName { get; set; }

        [Required]
        [Display(Name = "Email")]
        public string Email { get; set; }

        [Required]
        [Display(Name = "Username")]
        public string Username { get; set; }


    }

I want to post it to backend via <EditForm> component, and before I do that do the validation on client side. I also want to localize it like i would on aspnet.core server - Error/validation messages and display names...

I tried with LocalizedValidator component:

    public class MessageValidatorBase<TValue> : ComponentBase, IDisposable
    {
        private FieldIdentifier _fieldIdentifier;
        private EventHandler<ValidationStateChangedEventArgs> _stateChangedHandler
            => (sender, args) => StateHasChanged();
        [CascadingParameter]
        private EditContext EditContext { get; set; }
        [Parameter]
        public Expression<Func<TValue>> For { get; set; }
        [Parameter]
        public string Class { get; set; }
        protected IEnumerable<string> ValidationMessages =>
            EditContext.GetValidationMessages(_fieldIdentifier);
        protected override void OnInitialized()
        {
            _fieldIdentifier = FieldIdentifier.Create(For);
            EditContext.OnValidationStateChanged += _stateChangedHandler;
        }
        public void Dispose()
        {
            EditContext.OnValidationStateChanged -= _stateChangedHandler;
        }
    }

and then created component:

@typeparam TValue
@inherits MessageValidatorBase<TValue>
@inject StringLocalizationService _localizer
@foreach (var message in ValidationMessages)
{
    <div class="@Class">
        @_localizer[message]
        
    </div>
}

but the problem is I get already expanded string here. For example if I have error message like this "The field {0} is required" I get "The field First name is required" which will not be localized since I don't have the resource with that key and I don't intend to translate the same error message for every property name...

[EDIT] I just want to know if there is something trivial I didn't do instead of implementing it completely on my own

WebAssembly example.

Example property

[MaxLength(5,  ErrorMessageResourceName = "LengthError", ErrorMessageResourceType = typeof(Resources.App))]
public string Prefix { get; set; }

Create a folder in your client called Resources. Add a `.resx' file for each language plus a default (no language).

在此处输入图像描述

Make sure your set the access Modifier to Public 在此处输入图像描述

Example output in French.

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM