编辑专业

创建2个Edit动作

创建2个Edit动作,其中一个接收Guid类型的参数id,用于返回视图,另一个接收MajorViewModel类型的参数model,用于接收视图传递过来的数据,并在数据库中更新。

代码如下:

public IActionResult Edit(Guid id)
{
    return View();
}

[HttpPost]
public IActionResult Edit(MajorViewModel model)
{
    return RedirectToAction("Index");
}

创建Get方法

在进入编辑页面时,通常会指定要修改数据的id,并且在进入页面后会直接显示当前数据的值。

因此Edit动作需要接收id,并通过id获取MajorViewModel

于是需要在Service中创建Get方法来做这件事情。

需要注意的是,由于接收的id不一定能找到对应的数据,因此返回的值可能为,这时需要抛出异常

如果数据不为空,则将找到的数据转换为视图模型并返回。

代码如下:

public MajorViewModel Get(Guid id)
{
    Major? major = majorRepo.Get(id);
    if (major == null)
    {
        throw new NullReferenceException();
    }

    MajorViewModel model = new MajorViewModel()
    {
        Id = major.Id,
        Name = major.Name,
    };
    return model;
}

返回模型

在Edit动作中,通过Service的Get方法获取视图模型,如果捕获异常,则返回NotFound(),否则将视图模型返回给视图。

代码如下:

public IActionResult Edit(Guid id)
{

    MajorViewModel model;
    try
    {
        model = majorService.Get(id);
    }
    catch (NullReferenceException)
    {
        return NotFound();
    }
    return View(model);
}

添加编辑按钮

回到Index视图,添加一个名为操作的标题,并在tbody中添加一个<td>标签,用于显示编辑按钮。

代码如下:

<table class="table is-bordered is-striped is-hoverable is-fullwidth">
    <thead>
        <tr>
            <th>专业名称</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>
        @foreach (MajorViewModel major in Model)
        {
            <tr>
                <td>@major.Name</td>
                <td>
                    <a asp-action="Edit" asp-route-id="@major.Id" class="button is-warning">编辑</a>
                </td>
            </tr>
        }
    </tbody>
</table>

在代码中,asp-action表示将a标签的地址解析为当前控制器下的Edit动作,也就是/Major/Editasp-route-id表示在地址后面接一个id,例如,如果id为123,则地址为/Major/Edit/123

添加编辑视图

添加一个名为Edit.cshtml的视图文件。

然后可以直接将Add.cshtml中的代码粘贴过来。

将标题改为修改专业

最后添加一个隐藏的Id属性的input标签即可。

代码如下:

@{
    ViewBag.Title = "修改专业";
}
@model MajorViewModel

<form method="post" class="mx-auto" style="width:320px;">
    <input asp-for="Id" hidden/>
    <div class="field">
        <label asp-for="Name" class="label"></label>
        <div class="control">
            <input asp-for="Name" class="input">
        </div>
    </div>
    <div class="field">
        <button class="button is-primary is-fullwidth">提交</button>
    </div>
</form>

新增Id的原因是添加专业的时候,Id是自动生成的,而修改专业的时候,因为要指定修改哪个专业,因此要附带Id的值。

form表单如果不指定action,会将数据提交给当前视图同名Action

接收数据并更新数据

解下来的步骤就比较简单了:

  1. MajorController的Edit动作接收MajorViewModel类型的数据model,并将model传递给MajorService。
  2. MajorService将视图模型的数据转换为模型,并调用MajorRepo的Update方法。

因此,首先在MajorService创建Update方法,代码如下:

public void Update(MajorViewModel model)
{
    Major major = new Major()
    {
        Id = model.Id,
        Name = model.Name,
    };
    majorRepo.Update(major);
}

其次,在MajorController中调用MajorService的Update方法,然后重定向到首页,代码如下:

[HttpPost]
public IActionResult Edit(MajorViewModel model)
{
    majorService.Update(model);
    return RedirectToAction("Index");
}