Search code examples
c#asp.net-core-webapidata-annotationsasp.net-core-localization

Data annotation localization in .net core api


I'm trying to localize data annotation for multi lingual support,

while doing so I'm getting an access modifier error message, more details are divulged below.

Also If someone can provide me with example for data annotation localization in api, it will be highly appreciated, thanks in advance.

builder.Services.AddMvc()
.AddDataAnnotationsLocalization(options =>
{
    options.DataAnnotationLocalizerProvider = (type, factory) =>
        factory.Create(typeof(ValidationResources));
});

I've added this bit of code in program.cs

[Required(ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "ErrorMessage")]
        public string PhoneNumber { get; set; }
        public string? Name { get; set; }

This my is model class

I'm adding culture from resource filter

public class SetCultureAttribute : Attribute , IAsyncResourceFilter
    {

        public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
        {
            string languagePreference = "en-US";

            // Extract the bearer token from the Authorization header
            string token = context.HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");

            string headerPreference = string.Empty;

            if (context.HttpContext.Request.Headers.ContainsKey("LanguageCode"))
            {
                headerPreference = context.HttpContext.Request.Headers["LanguageCode"].ToString();
            }

            string actionName = context.ActionDescriptor.DisplayName;

            if (!string.IsNullOrEmpty(headerPreference))
            {
                CultureInfo.CurrentCulture = new CultureInfo(headerPreference);
                CultureInfo.CurrentUICulture = new CultureInfo(headerPreference);
            }
            else
            {
                // Validate and decode the token (example using JwtSecurityTokenHandler)
                if (!string.IsNullOrEmpty(token))
                {
                    var tokenHandler = new JwtSecurityTokenHandler();
                    var jwtToken = tokenHandler.ReadJwtToken(token);

                    // Extract user information from the token's claims
                    string email = jwtToken.Claims.FirstOrDefault(c => c.Type == "Name")?.Value;

                    //var userId = context.HttpContext.User.FindFirst("UserId")?.Value;
                    var userManager = context.HttpContext.RequestServices.GetService<UserManager<AppUsers>>();
                    AppUsers user = new AppUsers();
                    if (userManager != null)
                    {
                        user = await userManager.FindByEmailAsync(email);
                    }


                    // You can also fetch the user based on other request information such as a token or session

                    if (user != null)
                    {
                        languagePreference = user.Language;
                    }
                    CultureInfo.CurrentCulture = new CultureInfo(languagePreference);
                    CultureInfo.CurrentUICulture = new CultureInfo(languagePreference);

                }
            }

            await next();
        }
    }

I've also added respective resource files in ValidationResources class.

but still I'm getting this error The resource type 'BookStore.API.ResourcesDemo.ValidationResources' does not have an accessible static property named 'ErrorMessage'.

I've changed the access modifier to public, what am I missing?


Solution

  • The error is caused by ErrorMessageResourceName = "ErrorMessage"

    as the error message indicates,it required a static property named of ErrorMessage in ValidationResources class

    since you've configured

    .AddDataAnnotationsLocalization(options =>
    {
        options.DataAnnotationLocalizerProvider = (type, factory) =>
            factory.Create(typeof(ValidationResources));
    });
    

    It was not required

    ErrorMessageResourceType = typeof(ValidationResources), ErrorMessageResourceName = "ErrorMessage")
    

    Just try with [Required(ErrorMessage = "...")]

    What I tried:

    enter image description here

    enter image description here

    And notice rootnamespace

    For localliazation ,add different resx such assharedresource.en-us.resx,sharedresource.zh-cn.resx,follow the example in this document