我已经在我的Asp.Net Core MVC 3.0应用中实现了这个nuget包的本地化,并且发现它非常棒。
https:/github.comLazZiyaExpressLocalization)。
除了我的脚手架身份页面外,所有页面都能正常工作。
当我导航到我的脚手架Register.cshtml页面时,我遇到了一个问题,我的本地化cookie没有被放入URL中。但如果我输入文化(如 de
或 en
等)手动添加到URL中,本地化工作正常。
反而总是
启动.cs
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.EntityFrameworkCore;
using MyApp.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using LazZiya.ExpressLocalization;
using Microsoft.AspNetCore.Localization;
using MyApp.LocalizationResources;
using MyApp.Models;
namespace MyApp
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer( Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<ApplicationUser>( options => { options.SignIn.RequireConfirmedAccount = true; }).AddEntityFrameworkStores<ApplicationDbContext>();
services.AddControllersWithViews();
services.AddRazorPages();
var cultures = new []
{
new CultureInfo("de"),
new CultureInfo("en"),
};
services.AddControllersWithViews()
.AddExpressLocalization<LocSource>(ops =>
{
ops.UseAllCultureProviders = false;
ops.ResourcesPath = "LocalizationResources";
ops.RequestLocalizationOptions = o =>
{
o.SupportedCultures = cultures;
o.SupportedUICultures = cultures;
o.DefaultRequestCulture = new RequestCulture("en");
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
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();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseRequestLocalization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{culture=en}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(
name: "Features",
pattern: "{culture=en}/{controller=Features}/{action=Features}/{id?}");
endpoints.MapControllerRoute(
name: "About",
pattern: "{culture=en}/{controller=About}/{action=About}/{id?}");
endpoints.MapControllerRoute(
name: "Help",
pattern: "{culture=en}/{controller=Help}/{action=Help}/{id?}");
endpoints.MapRazorPages();
});
}
}
}
注册.cshtml.cs (我觉得这里有问题,因为我的MVC页面没有一个null的 returnUrl
)
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using MyApp.Data;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;
using LocSourceNameReferenceLibrary;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Http;
namespace MyApp.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class RegisterModel : PageModel
{
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly UserManager<ApplicationUser> _userManager;
private readonly ILogger<RegisterModel> _logger;
private readonly IEmailSender _emailSender;
RegisterPageLocSourceNames _locSourceRegisterPageNameReferenceLibrary = new RegisterPageLocSourceNames();
SharedCrossPageLocSourceNames _locSourceSharedCrossPageNameReferenceLibrary = new SharedCrossPageLocSourceNames();
public RegisterModel(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
ILogger<RegisterModel> logger,
IEmailSender emailSender)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
_emailSender = emailSender;
}
[BindProperty]
public InputModel Input { get; set; }
public string ReturnUrl { get; set; }
public string PageTabTitle { get; set; }
public string Title { get; set; }
public string SubTitle { get; set; }
public string Heading { get; set; }
public string ServiceHeading { get; set; }
public string EmailHeading { get; set; }
public string PasswordHeading { get; set; }
public string ConfirmPassword { get; set; }
public string RegisterButtonName { get; set; }
public string NavBarHome { get; set; }
public string NavBarFeatures { get; set; }
public string NavBarAbout { get; set; }
public string NavBarHelpCenter { get; set; }
public IList<AuthenticationScheme> ExternalLogins { get; set; }
public class InputModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm Password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
public async Task OnGetAsync(string returnUrl = null)
{
PageTabTitle = _locSourceRegisterPageNameReferenceLibrary.GetLocSourcePageTabTitleNameReferenceForRegisterPage();
Title = _locSourceRegisterPageNameReferenceLibrary.GetLocSourceTitleNameReferenceForRegisterPage();
SubTitle = _locSourceRegisterPageNameReferenceLibrary.GetLocSourceSubtitleNameReferenceForRegisterPage();
Heading = _locSourceRegisterPageNameReferenceLibrary.GetLocSourceHeadingNameReferenceForRegisterPage();
ServiceHeading = _locSourceRegisterPageNameReferenceLibrary.GetLocSourceServiceHeadingNameReferenceForRegisterPage();
EmailHeading = _locSourceRegisterPageNameReferenceLibrary.GetLocSourceEmailHeadingNameReferenceForRegisterPage();
PasswordHeading = _locSourceRegisterPageNameReferenceLibrary.GetLocSourcePasswordHeadingNameReferenceForRegisterPage();
ConfirmPassword = _locSourceRegisterPageNameReferenceLibrary.GetLocSourceConfirmPasswordHeadingNameReferenceForRegisterPage();
RegisterButtonName = _locSourceRegisterPageNameReferenceLibrary.GetLocSourceRegisterButtonNameReferenceForRegisterPage();
NavBarHome = _locSourceRegisterPageNameReferenceLibrary.GetLocSourceNavBarHomeReferenceForRegisterPage();
NavBarFeatures = _locSourceRegisterPageNameReferenceLibrary.GetLocSourceNavBarFeaturesReferenceForRegisterPage();
NavBarAbout = _locSourceRegisterPageNameReferenceLibrary.GetLocSourceNavBarAboutReferenceForRegisterPage();
NavBarHelpCenter = _locSourceRegisterPageNameReferenceLibrary.GetLocSourceNavBarHelpCenterReferenceForRegisterPage();
ReturnUrl = returnUrl;
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
}
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = Input.Email, Email = Input.Email };
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = user.Id, code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("RegisterConfirmation", new { email = Input.Email });
}
else
{
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
// If we got this far, something failed, redisplay form
return Page();
}
}
}
Areas > Identity > Pages > Account > _ViewImports.cshtml。
@using MyApp
@using MyApp.Areas.Identity.Pages.Account
@using LazZiya.ExpressLocalization
@inject ISharedCultureLocalizer _loc
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, LazZiya.TagHelpers
@addTagHelper *, LazZiya.ExpressLocalization
我还增加了一个 RouteTemplateModelConvention.cs。 根据 本说明但我不认为它在做什么。它在注释中说它应该被自动调用。我把它放在了根目录下 ~RouteTemplateModelConvention.cs
这是我的文件夹结构。
我猜是因为身份页面的脚手架自动使用了Razor页面来注册和登录,所以我的MVC本地化实现对这些页面不起作用。
但是...它 它是 如果我在浏览器的URL中手动添加文化("en "或 "de"),它就能正常工作,只是不能自动接收。
我尝试了很多方法来解决这个问题,但我确信是我在cookie的路由中遗漏了一些简单的东西......有什么想法吗?
更新。
我试着将文化参数添加到 <a></a>
连接 asp-route-culture=“@CultureInfo.CurrentCulture.Name”
在我的共同 _Layout.cshtml
文件,但得到一个错误,说 @CultureInfo
在当前上下文中不存在。
更新一下。
好了,有了进展,我添加了 @using System.Globalization
命名空间到我的布局文件.现在URL是 https://localhost:44305/"de"/Identity/Account/Register
我想弄明白为什么URL中会出现倒逗号?有什么好办法吗?
使用 asp-route-culture="@CultureInfo.CurrentCulture.Name"
应该可以解决这个问题。
在你的代码中,似乎你使用了倒置的逗号。“...”
要加引号 "..."
:)