为什么我的编辑方法在 ASP.NET Core 中不起作用

问题描述 投票:0回答:1

我在

EditEmployee
中有一个
AdminController
方法。当我提交编辑表单时,它显示错误 404。似乎该方法无法识别我绑定的
EmployeeId
,但我无法弄清楚

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> EditEmployee(int id, [Bind("EmployeeId,Name,Email,Password,RoleId,ShopId")] Employee employee)
{
    if (id != employee.EmployeeId)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(employee);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!_context.Employees.Any(e => e.EmployeeId == employee.EmployeeId))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }

    var errors = ModelState.Values.SelectMany(v => v.Errors);
    foreach (var error in errors)
    {
        Console.WriteLine(error.ErrorMessage);
    }

    ViewBag.RoleId = new SelectList(_context.Roles, "RoleId", "RoleName", employee.RoleId);
    ViewBag.ShopId = new SelectList(_context.RetailShops, "ShopId", "Address", employee.ShopId);
    return View(employee);
}

这是我的观点:

@model Nexus.Models.Employee
<div class="row">
    <div class="col-md-4">
        <form asp-action="EditEmployee" asp-controller="Admin" method="post">
            <div class="text-danger"></div>
            <div class="form-group">
                <label class="control-label">Name</label>
                <input asp-for="Name" class="form-control" />
                <span class="text-danger" asp-validation-for="Name"></span>
            </div>
            <div class="form-group">
                <label class="control-label">Email</label>
                <input asp-for="Email" class="form-control" />
                <span class="text-danger" asp-validation-for="Email"></span>
            </div>
            <div class="form-group">
                <label class="control-label">Password</label>
                <input asp-for="Password" class="form-control" />
                <span class="text-danger" asp-validation-for="Password"></span>
            </div>
            <div class="form-group">
                <label class="control-label">Role</label>
                <select asp-for="RoleId" class="form-control" asp-items="ViewBag.RoleId"></select>
                <span class="text-danger" asp-validation-for="RoleId"></span>
            </div>
            <div class="form-group">
                <label class="control-label">Shop address</label>
                <select asp-for="ShopId" class="form-control" asp-items="ViewBag.ShopId"></select>
                <span class="text-danger" asp-validation-for="ShopId"></span>
            </div>
            <br />
            <div class="form-group">
                <input type="submit" value="Submit" class="btn btn-primary" />
            </div>
        </form>
    </div>

我还尝试了另一种方法,使用

IFormCollection
,但它也不起作用:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> EditEmployee(int id, IFormCollection collection)
{
    try
    {
        var employee = await _context.Employees.FirstOrDefaultAsync(m => m.EmployeeId == id);
        if (employee == null)
        {
            return NotFound();
        }
        employee.EmployeeId = Convert.ToInt32(collection["EmployeeId"]);
        employee.Name = collection["Name"];
        employee.Email = collection["Email"];
        employee.Password = collection["Password"];
        employee.RoleId = Convert.ToInt32(collection["RoleId"]);
        employee.ShopId = Convert.ToInt32(collection["ShopId"]);
        _context.Update(employee);
        await _context.SaveChangesAsync();

        return RedirectToAction(nameof(Index));
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!_context.Employees.Any(e => e.EmployeeId == id))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Exception: {ex.Message}");
        return View();
    }
}

在这两种情况下,

EditEmployee
方法似乎都没有正确更新员工详细信息,我不确定为什么。
ModelState
无效,但我无法确定是什么原因造成的。

有人可以帮我理解我可能做错了什么吗?任何建议或改进将不胜感激。 我是 ASP.NET Core 新手,非常感谢。

c# asp.net-core-mvc
1个回答
0
投票

在这两种情况下,EditEmployee 方法似乎都没有更新 员工详细信息正确,我不确定为什么。模型状态是 无效,但我无法确定是什么原因导致的

根据您共享的代码片段,您收到 404 错误,并且由于编辑表单中缺少

Employee
,您的
Employee.EmployeeId
信息未更新。

因为当您发布编辑表单时,您的控制器期望

Employee.EmployeeId
尚未从您的帖子请求中传递,因此您的模型状态变为 false。

为了解决这个问题,您应该在编辑表单中包含以下代码。

 <input type="hidden" asp-for="Employee.EmployeeId" />

更新后的代码应该是:

查看:

@model Nexus.Models.Employee

<div class="row">
    <div class="col-md-4">
        <form asp-action="EditEmployee" asp-controller="Admin" method="post">
            <input type="hidden" asp-for="EmployeeId" />
            <div class="form-group">
                <label class="control-label">Name</label>
                <input asp-for="Employee.Name" class="form-control" />
                <span class="text-danger" asp-validation-for="Employee.Name"></span>
            </div>
            <div class="form-group">
                <label class="control-label">Email</label>
                <input asp-for="Employee.Email" class="form-control" />
                <span class="text-danger" asp-validation-for="Employee.Email"></span>
            </div>
            <div class="form-group">
                <label class="control-label">Password</label>
                <input asp-for="Employee.Password" class="form-control" />
                <span class="text-danger" asp-validation-for="Employee.Password"></span>
            </div>
            <div class="form-group">
                <label class="control-label">Role</label>
                <select asp-for="Employee.RoleId" class="form-control" asp-items="Model.RoleList"></select>
                <span class="text-danger" asp-validation-for="Employee.RoleId"></span>
            </div>
            <div class="form-group">
                <label class="control-label">Shop address</label>
                <select asp-for="Employee.ShopId" class="form-control" asp-items="Model.ShopList"></select>
                <span class="text-danger" asp-validation-for="Employee.ShopId"></span>
            </div>
            <br />
            <div class="form-group">
                <input type="submit" value="Submit" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

控制器:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult EditEmployee([Bind("EmployeeId,Name,Email,Password,RoleId,ShopId")] Employee employee)
{
    var existingEmployee = _employees.FirstOrDefault(e => e.EmployeeId == employee.EmployeeId);
    if (existingEmployee == null)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        existingEmployee.Name = employee.Name;
        existingEmployee.Email = employee.Email;
        existingEmployee.Password = employee.Password;
        existingEmployee.RoleId = employee.RoleId;
        existingEmployee.ShopId = employee.ShopId;

        return RedirectToAction(nameof(Index));
    }

    var viewModel = new EmployeeIndexViewModel
    {
        Employee = employee,
        RoleList = new List<SelectListItem>
    {
        new SelectListItem { Value = "1", Text = "Admin" },
        new SelectListItem { Value = "2", Text = "User" }
    },
        ShopList = new List<SelectListItem>
    {
        new SelectListItem { Value = "1", Text = "Shop 1" },
        new SelectListItem { Value = "2", Text = "Shop 2" }
    }
    };

    return View(viewModel);
}

输出:

enter image description here

enter image description here enter image description here

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.