ASP.NET Core Identity Razor Pages 用户编辑功能实现求助
Fixing ASP.NET Core Identity Edit Page with Razor Pages
It looks like your edit functionality is failing because you're mixing MVC patterns (like asp-action, asp-controller, and RedirectToAction) with Razor Pages, which has its own routing and model binding system. Let's walk through fixing this step by step.
First, Let's Identify the Key Issues in Your Current Code
- MVC-specific form attributes: Your
Edit.cshtmlusesasp-actionandasp-controller, which don't apply to Razor Pages. - Missing user ID in redirect: When you redirect to the Edit page from
OnPostChange, you aren't passing the user ID, so the Edit page can't load the target user. - Incorrect model binding: Your Edit page's fields aren't properly bound to the
ApplicationUsermodel, and yourOnPostEditmethod tries to use standalone properties (likeEmail,Score) instead of a bound model. - Wrong redirect method:
RedirectToActionis for MVC; Razor Pages usesRedirectToPage.
Step 1: Fix the Redirect from Index to Edit Page
Update your OnPostChange method in Index.cshtml.cs to pass the user ID to the Edit page:
public async Task<IActionResult> OnPostChange(string id) { var user = await _userManager.FindByIdAsync(id); if (user == null) { return NotFound(); } // Pass the user ID to the Edit page via route parameters return RedirectToPage("Edit", new { id = id }); }
Step 2: Rewrite the Edit Page Model (Edit.cshtml.cs)
We'll add an OnGetAsync method to load the user data when the page first loads, use [BindProperty] to bind the form data to the ApplicationUser model, and fix the update logic:
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace YourProjectNamespace.Pages { public class EditModel : PageModel { private readonly UserManager<ApplicationUser> _userManager; public EditModel(UserManager<ApplicationUser> userManager) { _userManager = userManager; } // Bind this property to the form data [BindProperty] public ApplicationUser ApUser { get; set; } // Load user data when the page is accessed via GET public async Task<IActionResult> OnGetAsync(string id) { if (id == null) { return NotFound(); } ApUser = await _userManager.FindByIdAsync(id); if (ApUser == null) { return NotFound(); } return Page(); } // Handle form submission for edits public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return Page(); // Return to page if validation fails } // Get the existing user from the database to update var existingUser = await _userManager.FindByIdAsync(ApUser.Id); if (existingUser == null) { return NotFound(); } // Update only the fields you need to change existingUser.Email = ApUser.Email; existingUser.UserName = ApUser.Email; // Keep UserName in sync with Email if required existingUser.Score = ApUser.Score; existingUser.Position = ApUser.Position; existingUser.Sequence = ApUser.Sequence; var result = await _userManager.UpdateAsync(existingUser); if (result.Succeeded) { // Redirect back to the user list page return RedirectToPage("Index"); } // Add any Identity errors to the model state for display foreach (var error in result.Errors) { ModelState.AddModelError(string.Empty, error.Description); } // Return to the edit page to show errors return Page(); } } }
Step 3: Fix the Edit Page Markup (Edit.cshtml)
Replace your existing form with Razor Pages-compatible markup, binding fields to the ApUser property and removing MVC-specific attributes:
@page "{id?}" @model YourProjectNamespace.Pages.EditModel <h1>Edit User</h1> <form method="post"> <div asp-validation-summary="All" class="text-danger"></div> <!-- Hidden field to retain the user ID --> <div class="form-group"> <input type="hidden" asp-for="ApUser.Id" /> </div> <div class="form-group"> <label asp-for="ApUser.Email" class="control-label">Email</label> <input type="email" asp-for="ApUser.Email" class="form-control" /> <span asp-validation-for="ApUser.Email" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="ApUser.Score" class="control-label">Score</label> <input type="number" asp-for="ApUser.Score" class="form-control" /> <span asp-validation-for="ApUser.Score" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="ApUser.Position" class="control-label">Position</label> <input type="text" asp-for="ApUser.Position" class="form-control" /> <span asp-validation-for="ApUser.Position" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="ApUser.Sequence" class="control-label">Sequence</label> <input type="number" asp-for="ApUser.Sequence" class="form-control" /> <span asp-validation-for="ApUser.Sequence" class="text-danger"></span> </div> <div class="form-group"> <input type="submit" value="Save" class="btn btn-primary" /> <a asp-page="Index" class="btn btn-secondary">Cancel</a> </div> </form>
Key Notes to Remember
- Razor Pages Routing: The
@page "{id?}"directive defines a route parameter for the user ID, making it accessible to theOnGetAsyncmethod. - Model Binding: The
[BindProperty]attribute tells Razor Pages to map form data directly to theApUserproperty. - Identity Best Practices: Always fetch the existing user from the database before updating, rather than using the bound model directly—this ensures Identity's internal tracking works correctly.
- Validation: Use data annotations (like
[Required],[EmailAddress]) on yourApplicationUserproperties to enable client-side and server-side validation.
内容的提问来源于stack exchange,提问作者DVice
相关产品推荐
相关产品推荐

