Skip to content

Commit

Permalink
Added Data Annotation Multilingual Error Messages (#56)
Browse files Browse the repository at this point in the history
* Added Multilingual Attributes and data annotations Messages in Register Data Model

* Added localization in RegisterConfirmation Model

* Added Localization in LoginWithRecoveryCodeModel

* Added localization in InputModel in LoginWithRecoveryCodeModel

* Added localization in ResetPasswordModel

* Added localization in InputModel in ResetPasswordModel

* Added Localization in LoginWith2Fa Model

* Added localization in LoginWith2fa in InputModel

* Added localization in Login Model

* Added localization in InputModel in LoginModel

* Added localization in InputModel in ForgotPasswordModel

* Added localization in ExternalLoginModel

* Add localization in ConfirmEmailChangeModel

* Add localization in ConfirmEmailModel

* Localize Password and Email in LoginModel

* Added localiation in ChangedPasswordModel

* Added Localization in DeltePersonalDataModel

* Add localization in Disable2faModel

* Added Localization in DownloadPersonalDataModel

* Added localization in Email Model

* Added Localization in EnableAuthenticatorModel

* Add Localization in ExternalLoginsModel

* Added Localization in GenerateRecoveryCodesModel

* Add Localization in IndexModel

* Added Localization in PersonalDataModel

* Add Localization in ResetAuthenticatorModel

* Added Localization in SetPasswordModel

* Added Localization in TwoFactorAuthenticationModel

* Add Localization in RegisterModel

* Add Localization in ForgotPasswordModel

* Add Localization in Identity Models Data Annotations

* Change Identity Layout

* Update Index View
  • Loading branch information
Valentin Stoev authored Jan 28, 2020
1 parent 0651ed4 commit a043145
Show file tree
Hide file tree
Showing 106 changed files with 9,318 additions and 123 deletions.
88 changes: 88 additions & 0 deletions AJS.Web/AJS.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,92 @@
<ProjectReference Include="..\AJS.Services\AJS.Services.csproj" />
</ItemGroup>


<ItemGroup>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\ExternalLoginModel+InputModel.bg.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\ExternalLoginModel+InputModel.en.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\ForgotPasswordModel+InputModel.bg.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\ForgotPasswordModel+InputModel.en.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\LoginModel+InputModel.bg.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\LoginModel+InputModel.en.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\LoginModel.bg.resx">
<Generator></Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\LoginModel.en.resx">
<Generator></Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\LoginWith2faModel+InputModel.bg.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\LoginWith2faModel+InputModel.en.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\LoginWithRecoveryCodeModel+InputModel.bg.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\LoginWithRecoveryCodeModel+InputModel.en.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\Manage\ChangePasswordModel+InputModel.bg.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\Manage\ChangePasswordModel+InputModel.en.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\Manage\DeletePersonalDataModel+InputModel.bg.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\Manage\DeletePersonalDataModel+InputModel.en.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\Manage\EmailModel+InputModel.bg.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\Manage\EmailModel+InputModel.en.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\Manage\EnableAuthenticatorModel+InputModel.bg.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\Manage\EnableAuthenticatorModel+InputModel.en.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\Manage\IndexModel+InputModel.bg.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\Manage\IndexModel+InputModel.en.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\Manage\SetPasswordModel+InputModel.bg.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\Manage\SetPasswordModel+InputModel.en.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\RegisterModel+InputModel.bg.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\RegisterModel+InputModel.en.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\ResetPasswordModel+InputModel.bg.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="Resources\Areas\Identity\Pages\Account\ResetPasswordModel+InputModel.en.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
</ItemGroup>

</Project>
9 changes: 6 additions & 3 deletions AJS.Web/Areas/Identity/Pages/Account/ConfirmEmail.cshtml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Localization;

namespace AJS.Web.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class ConfirmEmailModel : PageModel
{
private readonly UserManager<User> _userManager;
private readonly IStringLocalizer<ConfirmEmailModel> _localizer;

public ConfirmEmailModel(UserManager<User> userManager)
public ConfirmEmailModel(UserManager<User> userManager, IStringLocalizer<ConfirmEmailModel> localizer)
{
_userManager = userManager;
_localizer = localizer;
}

[TempData]
Expand All @@ -35,12 +38,12 @@ public async Task<IActionResult> OnGetAsync(string userId, string code)
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
{
return NotFound($"Unable to load user with ID '{userId}'.");
return NotFound(string.Format(_localizer[$"Unable to load user with ID '{0}'."], userId));
}

code = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(code));
var result = await _userManager.ConfirmEmailAsync(user, code);
StatusMessage = result.Succeeded ? "Thank you for confirming your email." : "Error confirming your email.";
StatusMessage = result.Succeeded ? _localizer["Thank you for confirming your email."] : _localizer["Error confirming your email."];
return Page();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Localization;

namespace AJS.Web.Areas.Identity.Pages.Account
{
Expand All @@ -17,11 +18,13 @@ public class ConfirmEmailChangeModel : PageModel
{
private readonly UserManager<User> _userManager;
private readonly SignInManager<User> _signInManager;
private readonly IStringLocalizer<ConfirmEmailChangeModel> _localizer;

public ConfirmEmailChangeModel(UserManager<User> userManager, SignInManager<User> signInManager)
public ConfirmEmailChangeModel(UserManager<User> userManager, SignInManager<User> signInManager, IStringLocalizer<ConfirmEmailChangeModel> localizer)
{
_userManager = userManager;
_signInManager = signInManager;
_localizer = localizer;
}

[TempData]
Expand All @@ -37,14 +40,14 @@ public async Task<IActionResult> OnGetAsync(string userId, string email, string
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
{
return NotFound($"Unable to load user with ID '{userId}'.");
return NotFound(string.Format(_localizer[$"Unable to load user with ID '{0}'."], userId));
}

code = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(code));
var result = await _userManager.ChangeEmailAsync(user, email, code);
if (!result.Succeeded)
{
StatusMessage = "Error changing email.";
StatusMessage = _localizer["Error changing email."];
return Page();
}

Expand All @@ -53,12 +56,12 @@ public async Task<IActionResult> OnGetAsync(string userId, string email, string
var setUserNameResult = await _userManager.SetUserNameAsync(user, email);
if (!setUserNameResult.Succeeded)
{
StatusMessage = "Error changing user name.";
StatusMessage = _localizer["Error changing user name."];
return Page();
}

await _signInManager.RefreshSignInAsync(user);
StatusMessage = "Thank you for confirming your email change.";
StatusMessage = _localizer["Thank you for confirming your email change."];
return Page();
}
}
Expand Down
16 changes: 10 additions & 6 deletions AJS.Web/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;

namespace AJS.Web.Areas.Identity.Pages.Account
Expand All @@ -24,17 +25,20 @@ public class ExternalLoginModel : PageModel
private readonly UserManager<User> _userManager;
private readonly IEmailSender _emailSender;
private readonly ILogger<ExternalLoginModel> _logger;
private readonly IStringLocalizer<ExternalLoginModel> _localizer;

public ExternalLoginModel(
SignInManager<User> signInManager,
UserManager<User> userManager,
ILogger<ExternalLoginModel> logger,
IEmailSender emailSender)
IEmailSender emailSender,
IStringLocalizer<ExternalLoginModel> localizer)
{
_signInManager = signInManager;
_userManager = userManager;
_logger = logger;
_emailSender = emailSender;
_localizer = localizer;
}

[BindProperty]
Expand All @@ -49,8 +53,8 @@ public ExternalLoginModel(

public class InputModel
{
[Required]
[EmailAddress]
[Required(ErrorMessage = "Email is required")]
[EmailAddress(ErrorMessage = "Invalid email")]
public string Email { get; set; }
}

Expand All @@ -72,13 +76,13 @@ public async Task<IActionResult> OnGetCallbackAsync(string returnUrl = null, str
returnUrl = returnUrl ?? Url.Content("~/");
if (remoteError != null)
{
ErrorMessage = $"Error from external provider: {remoteError}";
ErrorMessage = string.Format(_localizer[$"Error from external provider: {0}"],remoteError);
return RedirectToPage("./Login", new {ReturnUrl = returnUrl });
}
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
ErrorMessage = "Error loading external login information.";
ErrorMessage = _localizer["Error loading external login information."];
return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
}

Expand Down Expand Up @@ -116,7 +120,7 @@ public async Task<IActionResult> OnPostConfirmationAsync(string returnUrl = null
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
{
ErrorMessage = "Error loading external login information during confirmation.";
ErrorMessage = _localizer["Error loading external login information during confirmation."];
return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
}

Expand Down
2 changes: 1 addition & 1 deletion AJS.Web/Areas/Identity/Pages/Account/ForgotPassword.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
}

<h1>@ViewData["Title"]</h1>
<h4>Enter your email.</h4>
<h4>@Localizer["Enter your email."]</h4>
<hr />
<div class="row">
<div class="col-md-4">
Expand Down
5 changes: 3 additions & 2 deletions AJS.Web/Areas/Identity/Pages/Account/ForgotPassword.cshtml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ public ForgotPasswordModel(UserManager<User> userManager, IEmailSender emailSend

public class InputModel
{
[Required]
[EmailAddress]
[Required(ErrorMessage = "Email is required")]
[EmailAddress(ErrorMessage = "Invalid email")]
[Display(Name = "Email")]
public string Email { get; set; }
}

Expand Down
20 changes: 13 additions & 7 deletions AJS.Web/Areas/Identity/Pages/Account/Login.cshtml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using AJS.Data.Models;
using Microsoft.Extensions.Localization;

namespace AJS.Web.Areas.Identity.Pages.Account
{
Expand All @@ -22,16 +23,19 @@ public class LoginModel : PageModel
private readonly SignInManager<User> _signInManager;
private readonly ILogger<LoginModel> _logger;
private readonly IEmailSender _emailSender;
private readonly IStringLocalizer<LoginModel> _localizer;

public LoginModel(SignInManager<User> signInManager,
ILogger<LoginModel> logger,
UserManager<User> userManager,
IEmailSender emailSender)
IEmailSender emailSender,
IStringLocalizer<LoginModel> localizer)
{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_logger = logger;
_localizer = localizer;
}

[BindProperty]
Expand All @@ -46,12 +50,14 @@ public LoginModel(SignInManager<User> signInManager,

public class InputModel
{
[Required]
[EmailAddress]
[Required(ErrorMessage = "Email is required")]
[EmailAddress(ErrorMessage = "Invalid email")]
[Display(Name = "Email")]
public string Email { get; set; }

[Required]
[Required(ErrorMessage = "Password is required")]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }

[Display(Name = "Remember me?")]
Expand Down Expand Up @@ -100,7 +106,7 @@ public async Task<IActionResult> OnPostAsync(string returnUrl = null)
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
ModelState.AddModelError(string.Empty, _localizer["Invalid login attempt."]);
return Page();
}
}
Expand All @@ -119,7 +125,7 @@ public async Task<IActionResult> OnPostSendVerificationEmailAsync()
var user = await _userManager.FindByEmailAsync(Input.Email);
if (user == null)
{
ModelState.AddModelError(string.Empty, "Verification email sent. Please check your email.");
ModelState.AddModelError(string.Empty, _localizer["Verification email sent. Please check your email."]);
}

var userId = await _userManager.GetUserIdAsync(user);
Expand All @@ -134,7 +140,7 @@ await _emailSender.SendEmailAsync(
"Confirm your email",
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

ModelState.AddModelError(string.Empty, "Verification email sent. Please check your email.");
ModelState.AddModelError(string.Empty, _localizer["Verification email sent. Please check your email."]);
return Page();
}
}
Expand Down
Loading

0 comments on commit a043145

Please sign in to comment.