使用模型绑定和POST请求在每个表行上实现删除按钮

如何解决使用模型绑定和POST请求在每个表行上实现删除按钮

在我看来,我有一个表,该表具有要用于删除特定行的表单。我使用一个foreach循环来生成一个隐藏的输入字段,其中包含要传递给控制器​​的行值和用于模型出价的asp-for标签,以及一个提交按钮。

传递给控制器​​的值始终是第一行。我倾向于认为此行为的原因是,生成的输入字段都具有相同的name属性,因为asp-for表达式对于foreach循环的每次迭代都是不变的。

是否有使用表单和POST请求来实现此目的的简单方法,还是应该只使用带有路由值的锚点(即GET请求)?

这是我的ViewModel:

public class RolesViewModel
}
    public IList<AppUser> UsersInRole {get; set;}
    public string SelectedRole {get; set;}
    public RemoveUserFromRole RemoveUser {get; set;}

    public class RemoveUserFromRole 
    {
        public string UserName {get; set;}
        public string RoleName {get; set;}
    }
}

我的视图

<form method="post" asp-action="RemoveUser" id="removeUserForm"></form>
<table id="userTable" class="table table-striped table-sm">
    <thead>
        <tr>
            <th scope="col">User name</th>
            <th scope="col" class="text-center">Delete</th>
        </tr>
    </thead>
    <tbody>
    @foreach (var user in Model.UsersInRole)
    {
        <tr>
            <td>@user.UserName</td>
            <td class="text-center">
                <input form="removeUserForm" asp-for="RemoveUser.UserName" type="hidden" value="@user.UserName" />
                <input form="removeUserForm" asp-for="RemoveUser.RoleName" type="hidden" value="@Model.SelectedRoleName" />
                <button form="removeUserForm" type="submit" class="btn btn-sm btn-link text-danger py-0 my-0">
                    <i class="fas fa-times"></i>
                </button>
            </td>
        </tr>
    }
    </tbody>
</table>

还有我在控制器中的操作方法

[HttpPost]
public async Task<IActionResult> RemoveUser(RolesViewModel model)
{
    //model.RemoveUser.UserName always have the value from the first row
    var user = await _userManager.FindByNameAsync(model.RemoveUser.UserName);
    if (user == null)
        return RolesError(await GetModel());

    var result = await _userManager.RemoveFromRoleAsync(user,model.RemoveUser.RoleName);
    if (!result.Succeeded)
        return RolesError(await GetModel());


    return RedirectToAction("Roles",new { roleName = model.RemoveUser.RoleName });
}

提前感谢您的时间。

解决方法

根据您的代码,我发现您有多个包含user.UserName的隐藏文件。

如果单击提交按钮,它将所有隐藏的字段值上传到代码隐藏区,并且仅绑定第一个值,这就是为什么模型始终是第一个值的原因。

您可以在F12开发工具的网络中找到表单数据。

enter image description here

要解决此问题,我们有一个简单但不好的解决方案。

我们可以在您的表中设置多个表单标签,以避免将所有隐藏的归档用户名值都发布到控制器:

像下面这样:

<table id="userTable" class="table table-striped table-sm">
    <thead>
        <tr>
            <th scope="col">User name</th>
            <th scope="col" class="text-center">Delete</th>
        </tr>
    </thead>

    <tbody>

         @foreach (var user in Model.UsersInRole)
         { int i = 0;



            <tr>

                <td>@user.UserName</td>
                <td class="text-center">
        <form method="post" asp-action="RemoveUser" id="@user.UserName">

                    <input form="@user.UserName" name="RemoveUser.UserName" type="hidden" value="@user.UserName" />
                    <input form="@user.UserName" name="RemoveUser.RoleName" type="hidden" value="@Model.SelectedRole" />
                    <button form="@user.UserName" type="submit" class="btn btn-sm btn-link text-danger py-0 my-0">
                        <i class="fas fa-times">iiiii</i>
                    </button>
        </form>
                </td>

            </tr>

                }
    
        </tbody>
</table>

如果选择这种方式,则应重建视图的所有HTML组成。

此外,您可以尝试使用ajax来满足您的要求,该解决方案比以前的解决方案更好。您可以根据提交按钮的ID或位置使用jquery获取正确的表单数据,然后使用jquery ajax将表单数据发布到控制器中。然后,您可以返回重定向URL而不是RedirectToAction方法。

有关如何使用ajax发送表单数据的更多详细信息,您可以参考以下代码:

@model MVCRelatedIssue.Models.RolesViewModel
@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<form method="post" asp-action="RemoveUser" id="removeUserForm">

    <table id="userTable" class="table table-striped table-sm">
        <thead>
            <tr>
                <th scope="col">User name</th>
                <th scope="col" class="text-center">Delete</th>
            </tr>
        </thead>

        <tbody>

            @foreach (var user in Model.UsersInRole)
            {
                <tr>

                    <td>@user.UserName</td>
                    <td class="text-center">
                        <input form="removeUserForm" name="RemoveUser.UserName" type="hidden" value="@user.UserName" />
                        <input form="removeUserForm" name="RemoveUser.RoleName" type="hidden" value="@Model.SelectedRole" />
                        <button form="removeUserForm" type="submit" id="submit" class="btn btn-sm btn-link text-danger py-0 my-0 subbtn">
                            <i class="fas fa-times">iiiii</i>
                        </button>
                    </td>

                </tr>

            }

        </tbody>
    </table>
</form>

@section Scripts{
    <script>
        $(document).ready(function () {
            $(".subbtn").bind("click",function (e) {
                e.preventDefault();
                var formdata = new FormData();
                var UserName = $(this).prev().prev().val();
                formdata.append("RemoveUser.UserName",UserName);
                console.log(UserName);
                var roleName = $(this).prev().val();
                formdata.append("RemoveUser.RoleName",roleName);
                console.log(roleName);

                $.ajax({
                    type: "POST",url: "/RemoveUser/RemoveUser",data: formdata,contentType: false,processData: false,success: function (data) {
                        alert("success");
        
                        window.location.href = data;
                    }
                });

             });
        }); 
    </script>
}

控制器:

    [HttpPost]
    public async Task<IActionResult> RemoveUser(RolesViewModel model)
    {
        //model.RemoveUser.UserName always have the value from the first row
        //var user = await _userManager.FindByNameAsync(model.RemoveUser.UserName);
        //if (user == null)
        //    return RolesError(await GetModel());

        //var result = await _userManager.RemoveFromRoleAsync(user,model.RemoveUser.RoleName);
        //if (!result.Succeeded)
        //    return RolesError(await GetModel());

         string redirecturl = "/RemoveUser/Roles?roleName=" + model.RemoveUser.RoleName;

        return Ok(redirecturl);
    }

结果:

enter image description here

,

您可以使用删除链接 在视图中

@foreach (var user in Model.UsersInRole)
{
    <a href="@Url.Action("RemoveUser","YOUR_Controller",new {username = user.UserName})"
                       onclick="return confirm('Do You want to Delete');" 
                    </a>
}

在控制器中

[HttpGet]
public async Task<IActionResult> RemoveUser(String username)
{
    // Get the user Object the delete it
}
,

我能够以最少的代码占用空间解决此问题。

事实证明,<td>标签可以具有形式,因此,知道这一点,就可以在每一行上具有不同的形式,如下所示:

查看:

//Remove inline table form
<table id="userTable" class="table table-striped table-sm">
    <thead>
        <tr>
            <th scope="col">User name</th>
            <th scope="col" class="text-center">Delete</th>
        </tr>
    </thead>
    <tbody>
    @foreach (var user in Model.UsersInRole)
    {
        <tr>
            <td>@user.UserName</td>
            <td class="text-center">
                //now each form will have the correct,row-wise formdata
                <form method="post" asp-action="RemoveUser">
                    <input asp-for="RemoveUser.UserName" type="hidden" value="@user.UserName" />
                    <input asp-for="RemoveUser.RoleName" type="hidden" value="@Model.SelectedRoleName" />
                    <button type="submit" class="btn btn-sm btn-link text-danger py-0 my-0">
                        <i class="fas fa-times"></i>
                    </button>
                </form>
            </td>
        </tr>
    }
    </tbody>
</table>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res