ارتقاء به ASP.NET Core 1.0 - قسمت 19 - بومی سازی
نویسنده: وحید نصیری
تاریخ: ۱۳۹۵/۰۵/۰۳ ۱۸:۲۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
<system.web>
<globalization uiCulture="fa-IR" culture="fa-IR" />
</system.web> protected void Application_BeginRequest()
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("fa-IR");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("fa-IR");
} public void Configure(IApplicationBuilder app)
{
app.UseRequestLocalization(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")
}
}); c='en-UK'|uic='en-US'
public IActionResult SetFaLanguage()
{
Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(new CultureInfo("fa-IR"))),
new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
);
return RedirectToAction("GetTitle");
}
public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
using System;
using System.Globalization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Localization;
using Microsoft.Extensions.Localization;
namespace Core1RtmEmptyTest.Controllers
{
public class TestLocalController : Controller
{
private readonly IStringLocalizer<TestLocalController> _stringLocalizer;
private readonly IHtmlLocalizer<TestLocalController> _htmlLocalizer;
public TestLocalController(
IStringLocalizer<TestLocalController> stringLocalizer,
IHtmlLocalizer<TestLocalController> htmlLocalizer)
{
_stringLocalizer = stringLocalizer;
_htmlLocalizer = htmlLocalizer;
}
public IActionResult Index()
{
var name = "DNT";
var message = _htmlLocalizer["<b>Hello</b><i> {0}</i>", name];
ViewData["Message"] = message;
return View();
}
[HttpGet]
public string GetTitle()
{
var about = _stringLocalizer["About Title"];
return about;
}
public IActionResult SetFaLanguage()
{
Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(new CultureInfo("fa-IR"))),
new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
);
return RedirectToAction("GetTitle");
}
}
} @using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@{
}
Message @ViewData["Message"]
<br/>
@Localizer["<b>Hello</b><i> {0}</i>", "DNT"]
<br/>
@Localizer["About Title"] using System.ComponentModel.DataAnnotations;
namespace Core1RtmEmptyTest.ViewModels.Account
{
public class RegisterViewModel
{
[Required(ErrorMessage = "EmailReq")]
[EmailAddress(ErrorMessage = "EmailType")]
[Display(Name = "Email")]
public string Email { get; set; }
}
}
// Dummy class to group shared resources
namespace Core1RtmEmptyTest
{
public class SharedResource
{
}
} IStringLocalizer<SharedResource> sharedLocalizer
@inject IHtmlLocalizer<SharedResource> SharedLocalizer
services.AddLocalization(options => options.ResourcesPath = "Sample.Resources"); services.AddLocalization(options => options.ResourcesPath = "Resources");
public TestLocalController(
IStringLocalizer<TestLocalController> stringLocalizer,
IHtmlLocalizer<TestLocalController> htmlLocalizer) private readonly IStringLocalizer _stringLocalizer;
private readonly IHtmlLocalizer _htmlLocalizer;
public TestLocalController(
IStringLocalizerFactory stringLocalizerFactory,
IHtmlLocalizerFactory htmlLocalizerFactory)
{
_stringLocalizer = stringLocalizerFactory.Create(
baseName: "Controllers.TestLocalController" /*مشخصات کنترلر جاری*/,
location: "Core1RtmTestResources.ExternalResources" /*نام اسمبلی ثالث*/);
_htmlLocalizer = htmlLocalizerFactory.Create(
baseName: "Controllers.TestLocalController" /*مشخصات کنترلر جاری*/,
location: "Core1RtmTestResources.ExternalResources" /*نام اسمبلی ثالث*/);
}
منبعی که با کادر قرمز مشخص کردم، به درستی کار میکنن و مشکلی نداره و از کلاسهای لایه domain میتونن ازش استفاده کنن. اما خب منطقی نیست برای هر کلاس یک منبع بسازم.
مساله ام، نحوه نامگذاری منبع اشتراکی هست. SharedResource رو هر گونه نامگذاری کردم، domain نتونست اونو بشناسه. صرفا نمیدونم که منبع اشتراکی رو چه نامی بهش بدم. نه نامگذاری تصویر بالا و نه تصویر پایین، هیچکدوم کار نکرد.
متشکرم.
services.AddMvc().AddDataAnnotationsLocalization(o =>
{
o.DataAnnotationLocalizerProvider = (type, factory) =>
{
return factory.Create(typeof(SharedResource));
};
});
services.AddLocalization(o =>
{
o.ResourcesPath = "Resources";
}); .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix, option =>
{
option.ResourcesPath = "Resources";
})
.AddDataAnnotationsLocalization(option =>
{
option.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(
baseName: type.FullName,
location: "x.Resources");
}); return factory.Create(
baseName: "SharedResource",
location: "Core3xRtmTestResources.ExternalResources" //نام اسمبلی ثالث
); public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(options =>
{
options.ResourcesPath = "Resources";
});
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization(options=>
{
options.DataAnnotationLocalizerProvider = (type, factory) =>
{
return factory.Create(
baseName: type.FullName /* بر این اساس نام فایل منبع متناظر باید به همراه ذکر فضای نام پایه آن هم باشد */,
location: "Core1RtmTestResources.ExternalResources" /*نام اسمبلی ثالث*/);
};
}); [Display(Name = "Email")]
@using Microsoft.AspNetCore.Mvc.Localization
@model Core1RtmTestResources.ViewModels.Account.RegisterViewModel
@inject IHtmlLocalizerFactory HtmlLocalizerFactory
@{
var localizer = HtmlLocalizerFactory.Create(
baseName: "Controllers.TestLocalController" /*مشخصات کنترلر جاری*/,
location: "Core1RtmTestResources.ExternalResources" /*نام اسمبلی ثالث*/);
var sharedLocalizer = HtmlLocalizerFactory.Create(
baseName: "SharedResource" /*مشخصات*/,
location: "Core1RtmTestResources.ExternalResources" /*نام اسمبلی ثالث*/);
}
Activate Persian Localization:
<a asp-controller="TestLocal" asp-action="SetFaLanguage">SetFaLanguage</a>
<br />
Message @ViewData["Message"]
<br />
@localizer["<b>Hello</b><i> {0}</i>", "DNT"]
<br />
@localizer["About Title"]
<br />
shared data: @sharedLocalizer["About Title"]
<form asp-controller="TestLocal" asp-action="Index" method="post" class="form-horizontal" role="form">
<input asp-for="Email" />
<span asp-validation-for="Email" class="text-danger"></span>
<input type="submit" />
</form> @{
CultureInfo.CurrentCulture =
CultureInfo.CurrentUICulture = PersianDateExtensionMethods.GetPersianCulture();
} public class FaLanguageActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
CultureInfo.CurrentCulture = new CultureInfo("fa-IR");
CultureInfo.CurrentUICulture = new CultureInfo("fa-IR");
base.OnActionExecuting(context);
}
} public abstract class MyCustomBaseView<TModel> : RazorPage<TModel>
{
protected MyCustomBaseView()
{
CultureInfo.CurrentCulture = new CultureInfo("fa-IR");
CultureInfo.CurrentUICulture = new CultureInfo("fa-IR");
} public class FaRequestCultureProvider : RequestCultureProvider
{
public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
{
return Task.FromResult(new ProviderCultureResult("fa-IR"));
}
} public void Configure(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")
}
};
requestLocalizationOptions.RequestCultureProviders.Insert(0, new FaRequestCultureProvider());
app.UseRequestLocalization(requestLocalizationOptions);
opts.DefaultRequestCulture = new RequestCulture(culture: "fa-IR", uiCulture: "fa-IR");
و طبق کامنتهای فوق، داخل Contractor رو هم اینطور تعریف میکنم:
_stringLocalizer = stringLocalizerFactory.Create(
baseName: "Controllers.LoginController",
location: "Zagros.Resources");
_htmlLocalizer = htmlLocalizerFactory.Create(
baseName: "Controllers.LoginController",
location: "Zagros.Resources");
ولی خب مقدار مورد نظر داخل فایل منبع برگردانده نمیشود؟
Custom tool ResXFileCodeGenerator failed to produce an output for input file 'Resource.fa.resx' but did not log a specific error.
مشکل از معرفی baseName بود که باید به جای
_stringLocalizer = stringLocalizerFactory.Create(
baseName: "Controllers.LoginController",
location: "Zagros.ExternalResources");
_htmlLocalizer = htmlLocalizerFactory.Create(
baseName: "Controllers.LoginController",
location: "Zagros.ExternalResources"); به دلیل اینکه در مسیر اصلی نیستیم، باید به این صورت معرفی شود (همراه مسیر فایل):
_stringLocalizer = stringLocalizerFactory.Create(
baseName: "Areas.Identity.Controllers.LoginController",
location: "Zagros.ExternalResources");
_htmlLocalizer = htmlLocalizerFactory.Create(
baseName: "Areas.Identity.Controllers.LoginController",
location: "Zagros.ExternalResources");
_stringLocalizer = stringLocalizerFactory.Create(
baseName: "Project3.Core.MetadataCore.TagsService.en.resx" ,
location: "Project.Apps.Office"); string TNTNT= _stringLocalizer["Title"].Value;
"Project.Apps.Office.Resources.Project.Core.MetadataCore.TagsService.en.resx"
'dotnet.exe' (CoreCLR: clrhost): Loaded 'C:\Users\kazemi\source\repos\Project\bin\Debug\netcoreapp2.1\en\Project.Models.Project.resources.dll'. Module was built without symbols. baseName: "Project3.Core.MetadataCore.TagsService.en.resx" ,
baseName: "Project3.Core.MetadataCore.TagsService",
<script type="text/javascript">
if (!window.resourceProvider) {
window.resourceProvider = {
message1: '',
message2: ''
};
}
</script> @using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@section Scripts
{
<script type="text/javascript">
resourceProvider.message1 = '@Localizer["About Title"]';
</script>
} <script type="text/javascript"> alert(resourceProvider.message1); </script>
@inject IHtmlLocalizerFactory HtmlLocalizerFactory
@{ var _sharedLocalizer = HtmlLocalizerFactory.Create(
baseName: "Shared.SharedMessages" /*مشخصات کنترلر جاری*/,
location: "Project.Resources" /*نام اسمبلی ثالث*/);
} public class LanguageRouteConstraint : IRouteConstraint
{
public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
{
if (!values.ContainsKey("lang"))
{
return false;
}
var lang = values["lang"].ToString();
var result = lang == "fa" || lang == "en";
return result;
}
} public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(o => o.ResourcesPath = "Resources");
services.Configure<RouteOptions>(options =>
{
options.ConstraintMap.Add("lang", typeof(LanguageRouteConstraint));
});
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization(); public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseRequestLocalization(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"),
},
RequestCultureProviders = new List<IRequestCultureProvider>()
{
new RouteDataRequestCultureProvider()
{
UIRouteDataStringKey = "lang",
RouteDataStringKey = "lang"
}
}
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "LocalizedAreas",
template: "{lang:lang}/{area:exists}/{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "LocalizedDefault",
template: "{lang:lang}/{controller=Home}/{action=Index}/{id?}"
);
routes.MapRoute(
name: "default",
template: "{*catchall}",
defaults: new { controller = "Home", action = "RedirectToDefaultLanguage" });
}); [Route("{culture}/[controller]")]
public class ValuesController : Controller
{
[Route("ShowMeTheCulture")]
public string GetCulture()
{
return $"CurrentCulture:{CultureInfo.CurrentCulture.Name}, CurrentUICulture:{CultureInfo.CurrentUICulture.Name}";
}
} services.AddMvc(options => options.EnableEndpointRouting = false) .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
app.UseAuthentication();
public static void ConfigureOptions(RequestLocalizationOptions options)
{
var supportedCultures = new List<CultureInfo>
{ new CultureInfo("fa"),
new CultureInfo("en"),
new CultureInfo("ar")
};
options.DefaultRequestCulture = new RequestCulture(culture: "fa", uiCulture: "fa");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders = new[] {
new RouteDataRequestCultureProvider()
{
Options = options,
RouteDataStringKey = "lang",
UIRouteDataStringKey = "lang"
}
};
} var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>(); LocalizationPipeline.ConfigureOptions(options.Value); app.UseRequestLocalization(options.Value);
var resultIdentity = await _signInManager.PasswordSignInAsync(username, password, rememberMe, lockoutOnFailure: true);
app.UseAuthentication();
<breadcrumb asp-homepage-title="@localizer["MyApp"]"
asp-homepage-url="@Url.Action("Index", "Home", values: new { area = "" })"
asp-bootstrap-version="V3"
asp-homepage-glyphicon="glyphicon glyphicon-home"></breadcrumb>
@localizer["About"] [BreadCrumb(Title = "Home", UseDefaultRouteUrl = true, Order = 0)]
public class HomeController : Controller
{
} var supportedCultures = new List<CultureInfo>
{
new CultureInfo("fa"),
new CultureInfo("en"),
new CultureInfo("ar")
};
services.Configure<RequestLocalizationOptions>(
options =>
{
options.DefaultRequestCulture = new RequestCulture("fa");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders = new List<IRequestCultureProvider> { new CookieRequestCultureProvider() };
});