我在编辑操作中收到 HTTP ERROR 404 异常
I am getting HTTP ERROR 404 Exception in Edit Action
这里是编辑代码:
[HttpGet]
public async Task<IActionResult> Edit(string id)
{
var roles = _roleManager.Roles.ToList();
ViewBag.Roles = new SelectList(roles, "Id", "Name");
ApplicationUser user = await _userManager.FindByIdAsync(id);
if (user == null)
{
ViewBag.ErrorMessage = $"User with Id = {id} cannot be found";
return NotFound();
}
var userRole = _userManager.GetRolesAsync(user).ToString();
var userViewModel = new EditUserViewModel
{
UserId=user.Id,
Username=user.UserName,
FirstName=user.FirstName,
LastName=user.LastName,
Email=user.Email,
UserPIN=user.UserPIN,
Address=user.Address,
TelephoneNumber=user.PhoneNumber,
Roles = userRole
};
return View(userViewModel);
}
[HttpPost]
public async Task<IActionResult> Edit(EditUserViewModel userViewModel)
{
var user = await _userManager.FindByIdAsync(userViewModel.UserId);
if (user == null)
{
ViewBag.ErrorMessage = $"User with Id = {userViewModel.UserId} cannot be found";
return NotFound();
}
else
{
user.UserName = userViewModel.Username;
user.FirstName = userViewModel.FirstName;
user.LastName = userViewModel.LastName;
user.Email = userViewModel.Email;
user.UserPIN = userViewModel.UserPIN;
user.Address = userViewModel.Address;
user.PhoneNumber = userViewModel.TelephoneNumber;
var result = await _userManager.UpdateAsync(user);
_dbContext.SaveChanges();
if (result.Succeeded)
{
return RedirectToAction("Index");
}
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
return View(userViewModel);
}
}
这是我要编辑的视图模型:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace Project.Models.UserViewModels
{
public class EditUserViewModel
{
public string UserId { get; set; }
[Required]
[StringLength(50, MinimumLength = 6,
ErrorMessage = "Username cannot be shorter than 6 characters and longer than 50.")]
public string Username { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(10, MinimumLength = 10,
ErrorMessage = "User PIN must be 10 characters long")]
public string UserPIN { get; set; }
[Required]
[StringLength(10, MinimumLength = 10,
ErrorMessage = "Telephone number must be 10 characters long")]
public string TelephoneNumber { get; set; }
[Required]
public string Address { get; set; }
[Required]
public string Roles { get; set; }
}
}
这是我的观点:
@model Project.Models.UserViewModels.EditUserViewModel
<h1>Edit User</h1>
<div class="col-md-4">
<form asp-action="Edit" asp-controller="Admin" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="FirstName"> First name</label>
<input asp-for="FirstName" class="form-control" />
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="LastName"> Last name</label>
<input asp-for="LastName" class="form-control" />
<span asp-validation-for="LastName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Username"> Username</label>
<input asp-for="Username" class="form-control" />
<span asp-validation-for="Username" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="UserPIN">User PIN</label>
<input asp-for="UserPIN" class="form-control" />
<span asp-validation-for="UserPIN" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Email"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="TelephoneNumber"></label>
<input asp-for="TelephoneNumber" class="form-control" />
<span asp-validation-for="TelephoneNumber" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Roles">Role</label>
<select asp-for="Roles" class="form-control" asp-items="@ViewBag.Roles"></select>
<span asp-validation-for="Roles" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Address">Address</label>
<input asp-for="Address" class="form-control" />
<span asp-validation-for="Address" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
<div>
<a asp-action="Index">Back to User list</a>
</div>
我使用 Identity 创建了一个 asp.net 核心应用程序。现在我正在定制项目。我写了 AddUser and role 和 Delete Actions,它们正在工作。
当我尝试在 UserList 中编辑我的用户时出现 HTTP ERROR 404 异常。
我添加了 _dbContext.SaveChanges(),但它仍然无法正常工作。其余的 CRUD 操作都像我之前说的那样正常工作。
你在 404 NotFound
.
那里有一个相当明显的错误
您创建和存储用户的方式不匹配,或者您尝试从 _userManager
检索用户的方式不匹配,特别是:
_userManager.FindByIdAsync(userViewModel.UserId)
- 调试
Edit
动作时,视图模型属性UserId
有值吗?
- 如果是,该值是否与创建用户时
UserId
的设置匹配?
- 要么在创建时修改数据,要么在编辑期间提供更多数据,以创建成功的匹配
保存模型的代码取决于 userViewModel.UserId
信息的存在。但这不存在于 .cshtml 代码中。因此,当模型在 HttpPost 中传递回控制器时,没有数据并且 _userManager.FindByIdAsync
将找不到任何用户。修复很简单,只需在 .cshtml 的某处添加 UserId
的隐藏字段
<form asp-action="Edit" asp-controller="Admin" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div> <input asp-for="UserId" class="d-none" /></div>
....
很难记住,从 HttpGet 操作传递到视图的 ViewModel 实例与传递回 HttpPost 操作的实例不同。它是一个新的 ViewModel 实例,它是从视图中存在的字段中填充的。如果您忘记了某个字段,那么传回给 post 操作的模型中就没有值。
这里是编辑代码:
[HttpGet]
public async Task<IActionResult> Edit(string id)
{
var roles = _roleManager.Roles.ToList();
ViewBag.Roles = new SelectList(roles, "Id", "Name");
ApplicationUser user = await _userManager.FindByIdAsync(id);
if (user == null)
{
ViewBag.ErrorMessage = $"User with Id = {id} cannot be found";
return NotFound();
}
var userRole = _userManager.GetRolesAsync(user).ToString();
var userViewModel = new EditUserViewModel
{
UserId=user.Id,
Username=user.UserName,
FirstName=user.FirstName,
LastName=user.LastName,
Email=user.Email,
UserPIN=user.UserPIN,
Address=user.Address,
TelephoneNumber=user.PhoneNumber,
Roles = userRole
};
return View(userViewModel);
}
[HttpPost]
public async Task<IActionResult> Edit(EditUserViewModel userViewModel)
{
var user = await _userManager.FindByIdAsync(userViewModel.UserId);
if (user == null)
{
ViewBag.ErrorMessage = $"User with Id = {userViewModel.UserId} cannot be found";
return NotFound();
}
else
{
user.UserName = userViewModel.Username;
user.FirstName = userViewModel.FirstName;
user.LastName = userViewModel.LastName;
user.Email = userViewModel.Email;
user.UserPIN = userViewModel.UserPIN;
user.Address = userViewModel.Address;
user.PhoneNumber = userViewModel.TelephoneNumber;
var result = await _userManager.UpdateAsync(user);
_dbContext.SaveChanges();
if (result.Succeeded)
{
return RedirectToAction("Index");
}
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
return View(userViewModel);
}
}
这是我要编辑的视图模型:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace Project.Models.UserViewModels
{
public class EditUserViewModel
{
public string UserId { get; set; }
[Required]
[StringLength(50, MinimumLength = 6,
ErrorMessage = "Username cannot be shorter than 6 characters and longer than 50.")]
public string Username { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(10, MinimumLength = 10,
ErrorMessage = "User PIN must be 10 characters long")]
public string UserPIN { get; set; }
[Required]
[StringLength(10, MinimumLength = 10,
ErrorMessage = "Telephone number must be 10 characters long")]
public string TelephoneNumber { get; set; }
[Required]
public string Address { get; set; }
[Required]
public string Roles { get; set; }
}
}
这是我的观点:
@model Project.Models.UserViewModels.EditUserViewModel
<h1>Edit User</h1>
<div class="col-md-4">
<form asp-action="Edit" asp-controller="Admin" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="FirstName"> First name</label>
<input asp-for="FirstName" class="form-control" />
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="LastName"> Last name</label>
<input asp-for="LastName" class="form-control" />
<span asp-validation-for="LastName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Username"> Username</label>
<input asp-for="Username" class="form-control" />
<span asp-validation-for="Username" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="UserPIN">User PIN</label>
<input asp-for="UserPIN" class="form-control" />
<span asp-validation-for="UserPIN" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Email"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="TelephoneNumber"></label>
<input asp-for="TelephoneNumber" class="form-control" />
<span asp-validation-for="TelephoneNumber" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Roles">Role</label>
<select asp-for="Roles" class="form-control" asp-items="@ViewBag.Roles"></select>
<span asp-validation-for="Roles" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Address">Address</label>
<input asp-for="Address" class="form-control" />
<span asp-validation-for="Address" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
<div>
<a asp-action="Index">Back to User list</a>
</div>
我使用 Identity 创建了一个 asp.net 核心应用程序。现在我正在定制项目。我写了 AddUser and role 和 Delete Actions,它们正在工作。
当我尝试在 UserList 中编辑我的用户时出现 HTTP ERROR 404 异常。
我添加了 _dbContext.SaveChanges(),但它仍然无法正常工作。其余的 CRUD 操作都像我之前说的那样正常工作。
你在 404 NotFound
.
您创建和存储用户的方式不匹配,或者您尝试从 _userManager
检索用户的方式不匹配,特别是:
_userManager.FindByIdAsync(userViewModel.UserId)
- 调试
Edit
动作时,视图模型属性UserId
有值吗? - 如果是,该值是否与创建用户时
UserId
的设置匹配? - 要么在创建时修改数据,要么在编辑期间提供更多数据,以创建成功的匹配
保存模型的代码取决于 userViewModel.UserId
信息的存在。但这不存在于 .cshtml 代码中。因此,当模型在 HttpPost 中传递回控制器时,没有数据并且 _userManager.FindByIdAsync
将找不到任何用户。修复很简单,只需在 .cshtml 的某处添加 UserId
<form asp-action="Edit" asp-controller="Admin" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div> <input asp-for="UserId" class="d-none" /></div>
....
很难记住,从 HttpGet 操作传递到视图的 ViewModel 实例与传递回 HttpPost 操作的实例不同。它是一个新的 ViewModel 实例,它是从视图中存在的字段中填充的。如果您忘记了某个字段,那么传回给 post 操作的模型中就没有值。