首页 > 解决方案 > 我在编辑操作中收到 HTTP ERROR 404 异常

问题描述

这是编辑的代码:

[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 操作正常工作。

标签: c#asp.net-mvcasp.net-corecrudasp.net-core-identity

解决方案


保存模型的代码取决于信息的存在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 操作。


推荐阅读