بومی سازی منابع در پروژههای ASP.NET Core Web API
نویسنده: وحید نصیری
تاریخ: ۱۳۹۹/۰۶/۲۸ ۱۴:۴۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
public static class LocalizationConfig
{
public static IMvcBuilder AddCustomLocalization(this IMvcBuilder mvcBuilder, IServiceCollection services)
{
mvcBuilder.AddDataAnnotationsLocalization(options =>
{
const string resourcesPath = "Resources";
string baseName = $"{resourcesPath}.{nameof(SharedResource)}";
var location = new AssemblyName(typeof(SharedResource).GetTypeInfo().Assembly.FullName).Name;
options.DataAnnotationLocalizerProvider = (type, factory) =>
{
// to use `SharedResource.fa.resx` file
return factory.Create(baseName, location);
};
});
services.AddLocalization();
services.AddScoped<IStringLocalizer>(provider =>
provider.GetRequiredService<IStringLocalizer<SharedResource>>());
services.AddScoped<ISharedResourceService, SharedResourceService>();
return mvcBuilder;
}
} public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
services.AddControllers().AddCustomLocalization(services);
} public static class LocalizationConfig
{
public static IApplicationBuilder UseCustomRequestLocalization(this IApplicationBuilder app)
{
var requestLocalizationOptions = new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture(new CultureInfo("fa-IR")),
SupportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("fa-IR")
},
SupportedUICultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("fa-IR")
}
};
app.UseRequestLocalization(requestLocalizationOptions);
return app;
}
} public class Startup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseCustomRequestLocalization();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
} using System.ComponentModel.DataAnnotations;
namespace Core3xSharedResource.Models.Account
{
public class RegisterModel
{
[Required(ErrorMessage = "Please enter an email address")] // -->> from the shared resources
[EmailAddress(ErrorMessage = "Please enter a valid email address")] // -->> from the shared resources
public string Email { get; set; }
}
} <?xml version="1.0" encoding="utf-8"?>
<root>
<data name="<b>Hello</b><i> {0}</i>" xml:space="preserve">
<value><b>سلام</b><i> {0}</i></value>
</data>
<data name="About Title" xml:space="preserve">
<value>درباره</value>
</data>
<data name="DNT" xml:space="preserve">
<value>.NET Tips</value>
</data>
<data name="SiteName" xml:space="preserve">
<value>DNT</value>
</data>
<data name="Please enter an email address" xml:space="preserve">
<value>لطفا ایمیلی را وارد کنید</value>
</data>
<data name="Please enter a valid email address" xml:space="preserve">
<value>لطفا ایمیل معتبری را وارد کنید</value>
</data>
</root> using Core3xSharedResource.Models.Account;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
namespace Core3xSharedResource.WebApi.Controllers
{
[ApiController]
[Route("[controller]")]
public class NormalIStringLocalizerController : ControllerBase
{
private readonly IStringLocalizer _localizer;
public NormalIStringLocalizerController(IStringLocalizer localizer)
{
_localizer = localizer;
}
[HttpGet]
public ActionResult<string> Get()
{
var localizedString = _localizer["About Title"];
if (localizedString.ResourceNotFound)
{
return NotFound($"The localization resource with ID:`{localizedString.Name}` not found. SearchedLocation: `{localizedString.SearchedLocation}`.");
}
return localizedString.Value;
}
[HttpPost]
public ActionResult<RegisterModel> Post(RegisterModel model)
{
return model;
}
}
}
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
namespace Core3xSharedResource.Services
{
public interface ISharedResourceService
{
string this[string index] { get; }
IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures);
string GetString(string name, params object[] arguments);
string GetString(string name);
}
public class SharedResourceService : ISharedResourceService
{
private readonly IStringLocalizer _sharedLocalizer;
private readonly ILogger<SharedResourceService> _logger;
private readonly IHttpContextAccessor _httpContextAccessor;
public SharedResourceService(
IStringLocalizer sharedHtmlLocalizer,
IHttpContextAccessor httpContextAccessor,
ILogger<SharedResourceService> logger
)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_sharedLocalizer = sharedHtmlLocalizer ?? throw new ArgumentNullException(nameof(sharedHtmlLocalizer));
_httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
}
public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures)
{
return _sharedLocalizer.GetAllStrings(includeParentCultures);
}
public string this[string index] => GetString(index);
public string GetString(string name, params object[] arguments)
{
var result = _sharedLocalizer.GetString(name, arguments);
logError(name, result);
return result;
}
private void logError(string name, LocalizedString result)
{
if (result.ResourceNotFound)
{
var acceptLanguage = _httpContextAccessor?.HttpContext?.Request?.Headers["Accept-Language"];
_logger.LogError($"The localization resource with Accept-Language:`{acceptLanguage}` & ID:`{name}` not found. SearchedLocation: `{result.SearchedLocation}`.");
}
}
public string GetString(string name)
{
var result = _sharedLocalizer.GetString(name);
logError(name, result);
return result;
}
}
} using System.ComponentModel.DataAnnotations;
namespace Core3xSharedResource.Models.Account
{
public class RegisterModel
{
[Required(ErrorMessage = "Please enter an email address")] // -->> from the shared resources
[EmailAddress(ErrorMessage = "Please enter a valid email address")] // -->> from the shared resources
public string Email { get; set; }
[Required(ErrorMessage = "The {0} field is required")]
[Display(Name = "User Name")]
public string UserName { get; set; }
}
} <?xml version="1.0" encoding="utf-8"?>
<root>
<data name="Please enter an email address" xml:space="preserve">
<value>لطفا ایمیلی را وارد کنید</value>
</data>
<data name="Please enter a valid email address" xml:space="preserve">
<value>لطفا ایمیل معتبری را وارد کنید</value>
</data>
<data name="The {0} field is required" xml:space="preserve">
<value>{0} را تکمیل کنید</value>
</data>
<data name="User Name" xml:space="preserve">
<value>نام کاربری</value>
</data>
</root>
ضمن اینکه اگر کسی بخواهد کار جدی اعتبارسنجی را در Web API انجام دهد بهتر است از Fluent Validation استفاده کند (که تبدیل به یک استاندارد برای آن شدهاست).