- 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/
创建使用.NET框架的asp.net页面时,访问该页面的客户端是否需要在其计算机上安装.NET框架? IE。用户访问www.fakesite.com/default.aspx,如果他们没有安装框架,他
我阅读了很多不同的博客和 StackOverflow 问题,试图找到我的问题的答案,但最后我找不到任何东西,所以我想自己问这个问题。 我正在构建一个应用程序,其中有一个长时间运行的工作线程,它执行一些
已锁定。这个问题及其答案是locked因为这个问题是题外话,但却具有历史意义。目前不接受新的答案或互动。 我一直想知道为什么微软为这样一个伟大的平台选择了一个如此奇怪的、对搜索引擎不友好的名称。他们就
.Net Framework .Net .NET Standard的区别 1、.NET Framework 在未来.NET Framework或许成为过去时,目前还是有很多地方在使用的。这一套
如果有选择的话,您会走哪条路? ASP.NET Webforms + ASP.NET AJAX 或 ASP.NET MVC + JavaScript Framework of your Choice
我有一个 Web 服务,它通过专用连接通过 https 使用第三方 Web 服务,我应用了 ServicePointManager.ServerCertificateValidationCallbac
为什么我应该选择ASP.NET Web Application (.NET Framework)而不是ASP.NET Core Web Application (.NET Framework)? 我在
我在网络上没有找到任何关于包含 .NET Standard、.NET Core 和 .NET Framework 项目的 .NET 解决方案的公认命名约定。 就我而言,我们在 .NET 框架项目中有以
.NET Compact 是 .NET 的完美子集吗? 假设我考虑了屏幕大小和其他限制并避免了 .NET Compact 不支持的类和方法,或者 .NET Compact 是一个不同且不兼容的 GUI
我已经阅读了所有我能找到的关于 connectionManagement 中的 maxconnection 设置的文章:即 http://support.microsoft.com/kb/821268
我现在正在使用asp.net mvc,想知道使用内置的Json或 Json.Net哪个是更好的选择,但我不确定一个人是否比另一个人有优势。 另外,如果我确实选择沿用Json.Net的路线,那么我应该选
在 Visual Studio 中,您至少可以创建三种不同类型的类库: 类库(.NET Framework) 类库(.NET 标准) 类库(.NET Core) 虽然第一个是我们多年来一直使用的,但我
.NET 和 ASP.NET 之间有什么区别?它们有什么关系? 最佳答案 ASP.Net 基于 .Net 框架构建,提供有关 Web 开发的附加功能。 你可以去看看wikipedia article
在安装更高版本(3.0)之前,我需要安装.net框架1.1和2.0吗?或者单独安装 3.0 框架就足够了,并为在早期框架版本上编写的软件提供支持?谢谢 ,丽然 最佳答案 不,您不必安装以前的框架。 我
我正在开发一个项目,人们可以“更新”类别,例如更改类别的名称。我收到以下消息 This is called after clicking update 按钮 with the SQL statemen
.NET 类 System.Net.CookieContainer 线程安全吗? --更新:交 key 答复-- 是否有任何方法可以确保异步请求期间修改的变量(即 HttpWebRequest.Coo
我正在使用 JScript.NET 在我编写的 C# WinForms 应用程序中编写脚本。它工作得很好,但我只是尝试在脚本中放置一些异常处理,但我无法弄清楚如何判断我的 C# 代码抛出了哪种类型的异
我需要你的帮助, 比如我有一个小数类型的变量,我想这样取整。 例如 3.0 = 3 3.1 = 4 3.2 = 4 3.3 = 4 3.4 = 4 3.5 = 4 3.6 = 4 3.7 = 4 3.
我使用过这样的代码:http://msdn.microsoft.com/en-us/library/dw70f090.aspx在 ASP.NET 中工作之前访问数据库(2-3 年前)。我没有意识到我正
自 ConfigurationManager .NET Standard 中不存在,检索正在执行的程序集的应用程序设置的最佳方法是什么,无论是 web.config或 appSettings.{env
我是一名优秀的程序员,十分优秀!