diff --git a/src/NuGetGallery/Controllers/UsersController.cs b/src/NuGetGallery/Controllers/UsersController.cs index 8826bc88ef..f608a47b4b 100644 --- a/src/NuGetGallery/Controllers/UsersController.cs +++ b/src/NuGetGallery/Controllers/UsersController.cs @@ -126,14 +126,14 @@ public virtual async Task TransformToOrganization(TransformAccount var adminUser = UserService.FindByUsername(transformViewModel.AdminUsername); if (adminUser == null) { - ModelState.AddModelError("AdminUsername", String.Format(CultureInfo.CurrentCulture, + ModelState.AddModelError(string.Empty, String.Format(CultureInfo.CurrentCulture, Strings.TransformAccount_AdminAccountDoesNotExist, transformViewModel.AdminUsername)); return View(transformViewModel); } if (!UserService.CanTransformUserToOrganization(accountToTransform, adminUser, out var errorReason)) { - ModelState.AddModelError("AdminUsername", errorReason); + ModelState.AddModelError(string.Empty, errorReason); return View(transformViewModel); } @@ -420,10 +420,10 @@ public virtual async Task ForgotPassword(ForgotPasswordViewModel m switch (result.Type) { case PasswordResetResultType.UserNotConfirmed: - ModelState.AddModelError("Email", Strings.UserIsNotYetConfirmed); + ModelState.AddModelError(string.Empty, Strings.UserIsNotYetConfirmed); break; case PasswordResetResultType.UserNotFound: - ModelState.AddModelError("Email", Strings.CouldNotFindAnyoneWithThatUsernameOrEmail); + ModelState.AddModelError(string.Empty, Strings.CouldNotFindAnyoneWithThatUsernameOrEmail); break; case PasswordResetResultType.Success: return SendPasswordResetEmail(result.User, forgotPassword: true); @@ -481,7 +481,7 @@ public virtual async Task ResetPassword(string username, string to } catch (InvalidOperationException ex) { - ModelState.AddModelError("", ex.Message); + ModelState.AddModelError(string.Empty, ex.Message); return View(model); } @@ -489,7 +489,7 @@ public virtual async Task ResetPassword(string username, string to if (!ViewBag.ResetTokenValid) { - ModelState.AddModelError("", Strings.InvalidOrExpiredPasswordResetToken); + ModelState.AddModelError(string.Empty, Strings.InvalidOrExpiredPasswordResetToken); return View(model); } diff --git a/src/NuGetGallery/ExtensionMethods.cs b/src/NuGetGallery/ExtensionMethods.cs index c5f2a7c542..09e20f2b5e 100644 --- a/src/NuGetGallery/ExtensionMethods.cs +++ b/src/NuGetGallery/ExtensionMethods.cs @@ -345,15 +345,24 @@ public static HtmlString ShowValidationMessagesFor(this HtmlH var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); var propertyName = metadata.PropertyName.ToLower(); - return html.ValidationMessageFor(expression, validationMessage: null, htmlAttributes: new Dictionary + return html.ValidationMessageFor(expression, validationMessage: null, htmlAttributes: new Dictionary(ValidationHtmlAttributes) { { "id", $"{propertyName}-validation-message" }, - { "class", "help-block" }, - { "role", "alert" }, - { "aria-live", "assertive" }, }); } + public static MvcHtmlString ShowValidationMessagesForEmpty(this HtmlHelper html) + { + return html.ValidationMessage(modelName: string.Empty, htmlAttributes: ValidationHtmlAttributes); + } + + private static IDictionary ValidationHtmlAttributes = new Dictionary + { + { "class", "help-block" }, + { "role", "alert" }, + { "aria-live", "assertive" }, + }; + public static string ToShortNameOrNull(this NuGetFramework frameworkName) { if (frameworkName == null) diff --git a/src/NuGetGallery/ViewModels/PasswordResetRequestViewModel.cs b/src/NuGetGallery/ViewModels/PasswordResetRequestViewModel.cs index 7f214a0684..d94c0aa6be 100644 --- a/src/NuGetGallery/ViewModels/PasswordResetRequestViewModel.cs +++ b/src/NuGetGallery/ViewModels/PasswordResetRequestViewModel.cs @@ -7,6 +7,7 @@ namespace NuGetGallery public class ForgotPasswordViewModel { [Required] + [StringLength(255)] [Display(Name = "Email")] public string Email { get; set; } } diff --git a/src/NuGetGallery/ViewModels/TransformAccountViewModel.cs b/src/NuGetGallery/ViewModels/TransformAccountViewModel.cs index a09a7107d2..fd3f4f2ca3 100644 --- a/src/NuGetGallery/ViewModels/TransformAccountViewModel.cs +++ b/src/NuGetGallery/ViewModels/TransformAccountViewModel.cs @@ -8,7 +8,7 @@ namespace NuGetGallery public class TransformAccountViewModel { [Required] - [StringLength(255)] + [StringLength(64)] [Display(Name = "Administrator")] public string AdminUsername { get; set; } } diff --git a/src/NuGetGallery/Views/Users/ForgotPassword.cshtml b/src/NuGetGallery/Views/Users/ForgotPassword.cshtml index d67d7c7445..a2eb5b8e90 100644 --- a/src/NuGetGallery/Views/Users/ForgotPassword.cshtml +++ b/src/NuGetGallery/Views/Users/ForgotPassword.cshtml @@ -26,6 +26,9 @@ @Html.ShowTextBoxFor(m => m.Email) @Html.ShowValidationMessagesFor(m => m.Email) +
+ @Html.ShowValidationMessagesForEmpty() +
diff --git a/src/NuGetGallery/Views/Users/Transform.cshtml b/src/NuGetGallery/Views/Users/Transform.cshtml index f5fd1a5bec..1d8cdab0e9 100644 --- a/src/NuGetGallery/Views/Users/Transform.cshtml +++ b/src/NuGetGallery/Views/Users/Transform.cshtml @@ -45,6 +45,9 @@ @Html.ShowTextBoxFor(m => m.AdminUsername) @Html.ShowValidationMessagesFor(m => m.AdminUsername) +
+ @Html.ShowValidationMessagesForEmpty() +
diff --git a/tests/NuGetGallery.Facts/Controllers/UsersControllerFacts.cs b/tests/NuGetGallery.Facts/Controllers/UsersControllerFacts.cs index 7358e6495d..847ee24706 100644 --- a/tests/NuGetGallery.Facts/Controllers/UsersControllerFacts.cs +++ b/tests/NuGetGallery.Facts/Controllers/UsersControllerFacts.cs @@ -283,7 +283,7 @@ public async Task ShowsErrorIfUserWasNotFound() Assert.NotNull(result); Assert.IsNotType(typeof(RedirectResult), result); - Assert.Contains(Strings.CouldNotFindAnyoneWithThatUsernameOrEmail, result.ViewData.ModelState["Email"].Errors.Select(e => e.ErrorMessage)); + Assert.Contains(Strings.CouldNotFindAnyoneWithThatUsernameOrEmail, result.ViewData.ModelState[string.Empty].Errors.Select(e => e.ErrorMessage)); } [Fact] @@ -301,7 +301,7 @@ public async Task ShowsErrorIfUnconfirmedAccount() Assert.NotNull(result); Assert.IsNotType(typeof(RedirectResult), result); - Assert.Contains(Strings.UserIsNotYetConfirmed, result.ViewData.ModelState["Email"].Errors.Select(e => e.ErrorMessage)); + Assert.Contains(Strings.UserIsNotYetConfirmed, result.ViewData.ModelState[string.Empty].Errors.Select(e => e.ErrorMessage)); } [Fact] @@ -2275,8 +2275,8 @@ public async Task WhenCanTransformReturnsFalse_ShowsError() // Assert Assert.NotNull(result); - Assert.Equal(1, controller.ModelState["AdminUsername"].Errors.Count); - Assert.Equal("error", controller.ModelState["AdminUsername"].Errors.First().ErrorMessage); + Assert.Equal(1, controller.ModelState[string.Empty].Errors.Count); + Assert.Equal("error", controller.ModelState[string.Empty].Errors.First().ErrorMessage); } [Fact] @@ -2294,11 +2294,11 @@ public async Task WhenAdminIsNotFound_ShowsError() // Assert Assert.NotNull(result); - Assert.Equal(1, controller.ModelState["AdminUsername"].Errors.Count); + Assert.Equal(1, controller.ModelState[string.Empty].Errors.Count); Assert.Equal( String.Format(CultureInfo.CurrentCulture, Strings.TransformAccount_AdminAccountDoesNotExist, "AdminThatDoesNotExist"), - controller.ModelState["AdminUsername"].Errors.First().ErrorMessage); + controller.ModelState[string.Empty].Errors.First().ErrorMessage); } [Fact]