You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何删除含双主键的数据库表行?MVC C#遇400错误求助

我之前也碰到过一模一样的问题!当用复合主键删除数据时,MVC的默认路由和模型绑定很容易踩坑,直接导致400 Bad Request错误。单个主键能正常工作是因为默认路由刚好匹配{id}参数,但复合主键需要传递多个值,得针对性调整代码,让我一步步帮你解决:

核心原因

HTTP 400错误本质是请求参数无法被MVC正确绑定到Controller方法,默认路由只支持单个id参数,复合主键的多个值没被正确传递或识别。


1. 先确保Model的复合主键配置正确

首先要明确标记模型的复合主键,让EF和MVC都能识别:

using System.ComponentModel.DataAnnotations;

public class YourModel
{
    // 标记第一个主键
    [Key]
    public int PrimaryKey1 { get; set; }
    // 标记第二个主键
    [Key]
    public int PrimaryKey2 { get; set; }
    
    // 其他业务属性
    public string Name { get; set; }
    public DateTime CreateTime { get; set; }
}

注意:如果用Fluent API配置EF,也要确保正确设置复合主键,比如在DbContext的OnModelCreating里添加:

modelBuilder.Entity<YourModel>()
            .HasKey(m => new { m.PrimaryKey1, m.PrimaryKey2 });

2. 修改Controller的Delete方法,支持多参数绑定

默认的Delete方法只接收单个id,要改成接收所有主键参数,同时调整路由匹配:

public class YourController : Controller
{
    private YourDbContext db = new YourDbContext();

    // GET: 删除确认页面,接收两个主键参数
    // 路由会匹配:YourController/Delete/1/2(1是PrimaryKey1,2是PrimaryKey2)
    public ActionResult Delete(int primaryKey1, int primaryKey2)
    {
        var targetItem = db.YourModels.Find(primaryKey1, primaryKey2);
        if (targetItem == null)
        {
            return HttpNotFound();
        }
        return View(targetItem);
    }

    // POST: 执行删除操作,同样接收两个主键参数
    [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    public ActionResult DeleteConfirmed(int primaryKey1, int primaryKey2)
    {
        var targetItem = db.YourModels.Find(primaryKey1, primaryKey2);
        db.YourModels.Remove(targetItem);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
}

3. 调整View,确保传递所有主键值

不管是生成删除链接,还是提交删除表单,都要把两个主键值传递给Controller:

列表页的删除链接(跳转到确认页面)

@foreach (var item in Model)
{
    <tr>
        <td>@item.PrimaryKey1</td>
        <td>@item.PrimaryKey2</td>
        <td>@item.Name</td>
        <td>
            @Html.ActionLink("删除", "Delete", new { primaryKey1 = item.PrimaryKey1, primaryKey2 = item.PrimaryKey2 }, new { @class = "btn btn-danger" })
        </td>
    </tr>
}

删除确认页的提交表单

要把两个主键作为隐藏字段加入表单,确保POST请求时能传递:

@model YourNamespace.YourModel

@{
    ViewBag.Title = "确认删除";
}

<h2>确认删除这条数据?</h2>
<div>
    <dl class="dl-horizontal">
        <dt>@Html.DisplayNameFor(m => m.PrimaryKey1)</dt>
        <dd>@Html.DisplayFor(m => m.PrimaryKey1)</dd>
        <dt>@Html.DisplayNameFor(m => m.PrimaryKey2)</dt>
        <dd>@Html.DisplayFor(m => m.PrimaryKey2)</dd>
        <dt>@Html.DisplayNameFor(m => m.Name)</dt>
        <dd>@Html.DisplayFor(m => m.Name)</dd>
    </dl>

    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        <!-- 隐藏字段传递主键 -->
        @Html.HiddenFor(m => m.PrimaryKey1)
        @Html.HiddenFor(m => m.PrimaryKey2)
        
        <button type="submit" class="btn btn-danger">确认删除</button>
        @Html.ActionLink("返回列表", "Index", null, new { @class = "btn btn-default" })
    }
</div>

额外注意点

  • 如果你的路由配置有自定义规则,要确保允许传递多个参数,避免路由冲突;
  • 测试时可以打开浏览器的开发者工具,查看请求的URL和FormData,确认两个主键值都被正确传递;
  • 如果还是报400,检查ModelState是否有验证错误(可以在Controller里加if (!ModelState.IsValid)判断)。

内容的提问来源于stack exchange,提问作者Luis Acuña

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:14:23