- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我不会对大家撒谎。我对这个问题已经无能为力了。我花了大约 4 个小时的时间尝试书中的每个解决方案来解决一个问题,我知道对于试图将本地化引入他们的 Web 应用程序的程序员来说,这个问题很常见。每当我尝试将我的网页文化从英语 (en-US) 更改为韩语 (ko-KR) 时,它都会默认恢复为默认设置的英语。我已经缩小了问题的范围,我知道我没有生成正确的响应 cookie,但我在网上找到的解决方案都没有,显然 非常常见问题对我有帮助。
我尝试刷新 cookie 和缓存,我添加了 Microsoft.AspNetCore.Localization;
和 Microsoft.Extensions.Localization;
扩展,我试过使用 isEssential
CookieOptions
的参数对象,我知道我的文件结构是正确的,并且我所有的 .resx 文件都在它们应该在的位置,因为当我使用 ?culture=ko-KR 手动将网站切换到韩语时,我能够看到我应该看到的所有翻译,我相信我已经正确配置了我的startup.cs、 Controller 文件和部分 View ,我需要一个生命线。
几天前,我按照在线教程设置了一个虚拟教程 Web 应用程序,并且能够成功改变该 Web 应用程序的文化。由于 cookie 的工作方式,我只能通过更改虚拟 Web 应用程序上的语言来更改主应用程序上的语言,这根本不可行。
这是我的代码的重要部分。
启动.cs
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json.Serialization;
using Serilog;
using Snape.DataLayer.Entities;
using Snape.Web.ScheduledProcessor;
using Snape.Web.Services;
using Snape.WebSecurity.Hashing;
using Snape.WebSecurity.Helpers;
using Snape.WebSecurity.Tokens;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.Threading.Tasks;
using System.Linq;
namespace Snape.Web
{
public class Startup
{
private readonly IConfiguration _configProvider;
private readonly SigningConfiguration _signConfig;
private readonly IConfigurationRoot _constantsConfigProvider;
public Startup(IConfiguration configuration)
{
_configProvider = configuration;
_signConfig = new SigningConfiguration();
// Loading Constants.json && Configuration.json
var configurationBuilder = new ConfigurationBuilder()
.AddJsonFile($"{_configProvider.GetSection("Constants").Value}", optional: false, reloadOnChange: true)
.AddJsonFile($"{_configProvider.GetSection("Version").Value}", optional: true, reloadOnChange: true);
_constantsConfigProvider = configurationBuilder.Build();
// Initializing Serilog
Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(configuration).CreateLogger();
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
services.AddDistributedMemoryCache(); // Adds a default in-memory implementation of IDistributedCache
services.AddSession(options => options.IdleTimeout = TimeSpan.FromHours(1));
/* Note this is commented out.
var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions()
{
Path = "/",
HttpOnly = false,
IsEssential = true, //<- there
Expires = DateTime.Now.AddMonths(1),
}; */
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
// we need to add localization to the project for views, controllers, and data annotations.
services.AddMvc()
// localization options are going to have their resources (language dictionary) stored in Resources folder.
.AddViewLocalization(opts => { opts.ResourcesPath = "Resources"; })
.AddViewLocalization(Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
// we are configuring the localization service to support a list of provided cultures.
services.Configure<RequestLocalizationOptions>(opts =>
{
// the list of supported cultures.
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("en"),
new CultureInfo("en-US"),
new CultureInfo("ko"),
new CultureInfo("ko-KR"),
};
// set the localization default culture as english
opts.DefaultRequestCulture = new RequestCulture("en-US");
// supported cultures are the supportedCultures variable we defined above.
// formatiting dates, numbers, etc.
opts.SupportedCultures = supportedCultures;
// UI strings that we have localized
opts.SupportedUICultures = supportedCultures;
});
services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
services.AddDbContext<SnapeDbContext>(options => options.UseLazyLoadingProxies().UseSqlite(_configProvider.GetConnectionString("SnapeDbConnection")));
services.AddSingleton(_constantsConfigProvider); // IConfigurationRoot
// *If* you need access to generic IConfiguration this is **required**
services.AddSingleton(_configProvider);
// Background task for data push
services.AddSingleton<IHostedService, DataPushingTask>();
// Background task for device's state check
services.AddSingleton<IHostedService, HeartbeatTask>();
// Background task for project's sync with cloud
services.AddSingleton<IHostedService, SyncingTask>();
// Background task for Purging
services.AddSingleton<IHostedService, PurgingTask>();
// Service for Internet Management
services.AddTransient<InternetService>();
services.Configure<TokenOptions>(_configProvider.GetSection("TokenOptions"));
var tokenOptions = _configProvider.GetSection("TokenOptions").Get<TokenOptions>();
services.AddSingleton<IPassportHasher, PasswordHasher>();
services.AddSingleton<ITokenHelper, TokenHelper>();
services.AddSingleton(_signConfig);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(jwtBearerOptions =>
{
jwtBearerOptions.RequireHttpsMetadata = false;
jwtBearerOptions.SaveToken = true;
jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters()
{
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = tokenOptions.Issuer,
ValidAudience = tokenOptions.Audience,
IssuerSigningKey = _signConfig.Key,
ClockSkew = TimeSpan.Zero
};
});
services.Configure<FormOptions>(options =>
{
options.ValueCountLimit = int.MaxValue;
options.ValueLengthLimit = 1024 * 1024 * 100; // 100MB max len form data
});
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-AU");
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-AU");
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env, ILoggerFactory loggerFactory)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
// Enabling Logger
loggerFactory.AddSerilog();
app.UseHttpsRedirection();
app.UseStaticFiles();
// specify that globalization is being used in the pipeline.
var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(options.Value);
app.UseCookiePolicy();
app.UseSession();
//Add JWToken to all incoming HTTP Request Header
app.Use(async (context, next) => {
var jwToken = context.Session.GetString("JWToken");
if (!string.IsNullOrEmpty(jwToken))
{
context.Request.Headers.Add("Authorization", "Bearer " + jwToken);
}
await next();
});
app.UseAuthentication();
app.UseStatusCodePages(context => {
var response = context.HttpContext.Response;
if (response.StatusCode == (int)HttpStatusCode.Unauthorized || response.StatusCode == (int)HttpStatusCode.Forbidden)
{
response.Redirect("/Account/Login");
if (Utilities.WebUtility.IsAjaxRequest(context.HttpContext.Request))
response.StatusCode = (int)HttpStatusCode.Unauthorized;
}
return Task.CompletedTask;
});
app.UseMvc(routes => {
routes.MapRoute(
name: "default",
template: "{controller=Account}/{action=Login}/{id?}");
routes.MapRoute(
"invalid_route",
"{*url}",
new { controller = "NotFound", action = "Index" });
});
#if RELEASE
if (_constantsConfigProvider.GetValue<bool>("CELLULAR_ON"))
{
Task.Run(async () => { await app.ApplicationServices.GetRequiredService<InternetService>().Enable(); });
}
#endif
}
}
}
public class AccountController : BaseController
{
// the localizer dictionary to translate languages for this controller.
readonly IStringLocalizer<AccountController> _localizer;
readonly IConfiguration _configProvider;
readonly IPersonFacade _personFacade;
readonly SnapeDbContext _dbContext;
readonly ITokenHelper _tokenHelper;
// AccountController constructor
public AccountController(IStringLocalizer<AccountController> localizer, SnapeDbContext dbContext, IConfiguration configuration, IPassportHasher passwordHasher, ITokenHelper tokenHandler,
IConfigurationRoot constantsConfig) : base(constantsConfig)
{
// initialize the localizer.
_localizer = localizer;
_dbContext = dbContext;
_tokenHelper = tokenHandler;
_configProvider = configuration;
_personFacade = new PersonFacade(dbContext);
}
[HttpPost] // annotation that specifies that this action is called on an HTTPPost
// this method needs to persist on both this page and any subsequent ones. Sets cookie for changed culture.
public IActionResult SetLanguage(string culture, string returnURL)
{
// set the cookie on the local machine of the Http Response to keep track of the language in question.
// append the cookie and its language options.
Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName, // name of the cookie
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)), // create a string representation of the culture for storage
new CookieOptions { Expires = DateTimeOffset.UtcNow.AddDays(1),
IsEssential = true, //<- there
} // expiration after one day.
);
return LocalRedirect(returnURL); // redirect to the original URL, the account page.
}
@using Microsoft.AspNetCore.Builder
@using Microsoft.AspNetCore.Localization
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Localization
@using Microsoft.Extensions.Options
@inject IViewLocalizer Localizer
@inject IOptions<RequestLocalizationOptions> LocOptions
@{
// this code finds out what cultures I am supporting.
// it is all defined in startup.cs
var requestCulture = Context.Features.Get<IRequestCultureFeature>();
var cultureItems = LocOptions.Value.SupportedUICultures // all the supported cultures.
.Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
.ToList();
}
<!-- Partial view in ASP.NET MVC is special view which renders a portion of view content. It is just like a user control of a web form application.
Partial views can be reusable in multiple views. It helps us to reduce code duplication. In other words a partial view enables us to render a view within the parent view.
This partial view will be placed inside the layout.cshtml file, which is a shared (this is key) view that is under the wing of the home controller, just like the Home Views are -->
<!-- This code displays the culture/language dropdown.-->
<!-- Title of the dropdown-->
<div title="@Localizer["Request culture provider:"] @requestCulture?.Provider?.GetType().Name">
<!-- another post method-->
<!-- this form will call the setLanguage method under the AccountController.cs file. Even though this is a shared view, it's shared nature means the AccountController can still see it and act off of it.-->
<form id="selectLanguage" asp-controller="Account" asp-action="SetLanguage" asp-route-returnUrl="@Context.Request.Path"
method="post" class="form-horizontal" role="form">
<!-- Select dropdown for the language selection -->
<!-- asp-for indicates -->
<a style="color:white"> @Localizer["Language"]</a>
<select name="culture" asp-for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems"></select>
<button type="submit" class="btn btn-default btn-xs">Save</button>
<!-- clicking on the save button will call the action setLanguage in the AccountController.-->
</form>
</div>
<!-- import the partial view for selecting languages _SelectLanguagePartial.cshtml -->
@await Html.PartialAsync("_SelectLanguagePartial");
isEssential = true
在
CookieOptions
覆盖startup.cs中定义的以下请求配置
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
最佳答案
services.AddMvc()
的订单和 services.Configure<RequestLocalizationOptions>
很重要。确保在 AddMvC
之前运行包括本地化在内的所有内容.
见 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/troubleshoot-aspnet-core-localization?view=aspnetcore-3.1 :
Localization middleware order The app may not localize because the localization middleware isn't ordered as expected. To resolve this issue, ensure that localization middleware is registered before MVC middleware. Otherwise, the localization middleware isn't applied
.AddMvc
:
app.UseRequestLocalization();
RequestLocalizationOptions
中遗漏了几行:
CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("ko-KR")
};
services.Configure<RequestLocalizationOptions>(options =>
{
options.DefaultRequestCulture = new RequestCulture("en-US");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders = new List<IRequestCultureProvider>
{
new QueryStringRequestCultureProvider(),
new CookieRequestCultureProvider()
};
});
CookieRequestCultureProvider
它监听 cookie。这应该是您的示例不起作用的第二个原因。
关于asp.net-core - 无法使用 ASP.NET CORE 2.2 生成用于本地化的响应 cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59750992/
翻译 silverlight 5 应用程序 (Prism + MEF) 的可用选项是什么? 如果可能的话,我想: 没有 resx 文件(我不喜欢它们的管理方式) 而是提取并翻译 xaml 字符串(我认
我可以同时使用这两种方法来本地化 $| 还是我应该使用其中一种来支持另一种? 方法一:备份“_init_scr”中$|的旧值,并在调用“_end_win”时将$|设置回旧值。方式 2:调用 local
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: C# localization , really confusing me 有人可以分享他们对大型 C# 应
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 6年前关闭。 Improve thi
我正在使用 Phoenix 框架开发多语言应用程序 到目前为止,路由器看起来像这样: scope "/:locale", App do pipe_through [:browser, :bro
我想为我的域对象添加本地化支持。我有以下几点: class Person { int Id; City city; } class City { int Id; str
我需要 BlackBerry 本地化方面的帮助。我在 http://na.blackberry.com/eng/developers/resources/developer_labs.jsp#tab_
我正在尝试通过关注 documentation 来本地化我的 Flutter 应用程序. 我想要实现的是,在动态构建小部件的同时,我想转换来自我的模型的数据。这是我迄今为止尝试过的 List.gene
如何更改 EKEventEditViewController 中的默认语言,即使我手动设置 AppleLanguages 对象,它也始终是英语 最佳答案 我通过向我的应用程序 plist 添加一个 L
我在 iphone 日期选择器中遇到本地化问题。我希望日期选择器仅以英语显示日期,但现在它需要在 iphone 设置中设置为区域的语言。我尝试了各种没有用的方法像下面这样。 在 uidatepicke
我的应用仅支持荷兰语和法语。英语不是此应用程序的可用语言。如果我想使用可本地化的字符串,则默认值始终设置为英语。我希望这是荷兰语。所以我所做的就是使用英语可本地化字符串文件并用荷兰语单词填充它。我遇到
我即将本地化 iPhone 应用程序。当用户的语言(iOS 系统语言)是德语时,我想使用不同的 URL。 我想知道这是否是正确的方法: NSURL *url = [NSURL URLWithStrin
我正在将我的 iPhone 应用程序本地化为多种语言,除了更改一些字符串之外,我还需要更改一些背景。是否可以查询iPhone并获取用户的语言代码? 谢谢! 最佳答案 看一下 NSLocale: NSS
在本地化的 Iphone(语言设置为希伯来语)上,当我们使用 Safari 查看网页并点击输入字段时,我们会在键盘上显示希伯来语的“下一个/上一个/完成”按钮。 当我们使用应用程序中嵌入的 UIWeb
是否有更好的方法来存储大量文本以在 laravel 中进行本地化?如果我的整个页面只是纯文本,那会很容易,但是我的几个页面具有复杂的布局,我需要添加多个字符串来将文本包裹在图像/链接/媒体等内容周围。
我正在尝试将我的应用程序本地化。我为支持的语言创建了所需的 string.arb 文件。 为什么AppLocalizations.of(context)需要上下文? 我只是想访问文件/语言环境文件/类
绑定(bind)到 double可能会产生以下验证错误 Value ... could not be converted. 使用 ExceptionValidationRule 时错误更健谈: Inp
我有一些 Delphi 经验,并且正在尝试使用 Lazarus 构建一个项目,这对我来说是全新的。 我想,我已经阅读了有关 Lazarus、翻译/国际化/本地化的所有可用信息,但我无法找到我真正想要的
我一直在尝试更新网站的语言。 Controller public function getUpdateLanguage(Request $request) { $request_dat
我正在为我们正在启动的一个项目寻找框架和 CMS,该项目是一个需要支持本地化内容的网站。 Laravel 看起来不错,并且当然允许您本地化 UI 内容,但它似乎本身并不支持存储在数据库中的内容的本地化
我是一名优秀的程序员,十分优秀!