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

ASP.NET Core MVC:未设置IDENTITY_INSERT却提示为OFF及CarId传递难题

租车预订系统问题排查与修复

问题描述

作为ASP.NET新手,开发租车预订系统时遇到两个核心问题:

  • 从Home/Index视图点击“查看详情”打开Details局部视图,再点击“立即预订”打开预订表单后,无法将选中车辆的Id传递至BookingController
  • 未手动设置Booking的Id字段,却触发**“IDENTITY_INSERT设置为OFF”**数据库异常

相关代码

Booking模型类

public class Booking
{
    [Key]
    public int Id { get; set; }

    public string FullName { get; set; }
    public string Country { get; set; }
    public string LicenseNumber { get; set; }
    public string LicenseIssueCountry { get; set; }

    public string PhoneNumber { get; set; }
    public string Email { get; set; }

    // 车辆关联部分
    public int? CarId { get; set; }
    [ForeignKey("CarTypeId")] // 此处存在错误,应关联CarId
    public virtual Car? Car { get; } // 需改为get; set;

    [DisplayName("取车日期")]
    public DateTime? PickUpDate { get; set; }

    [DisplayName("还车日期")]
    public DateTime? DropOffDate { get; set; }

    public double RentalDuration{ get; set; }
    public int rentalTotal { get; set; }

    public double RentalDurationCalculator(DateTime dDate, DateTime pDate)
    {
        TimeSpan timeSpan = pDate - dDate;
        double rDuration = timeSpan.TotalDays;
        
        return rDuration;
    }

    public double TotalCalculator(int idGiven, double rDuration)
    {
        Car car = new Car(); // 创建新Car对象,Id默认0,永远无法匹配传入的idGiven
        double rTotal = 0;

        if (car.Id == idGiven)
        {
            rTotal = car.CarPrice * rDuration;   
        }
        return rTotal;
    }
}

BookingController

using CarRentals.Models;
using CarRentals.Models.ViewModel;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace CarRentals.Controllers
{
    public class BookingController : Controller
    {
        private readonly ProjectDbContext _dbx;

        public BookingController(ProjectDbContext db)
        {
            _dbx = db;
        }

        public IActionResult Create()
        {
            Booking booking = new Booking();
            return View();
        }

        // 创建预订的POST方法
        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Create(Booking booking, int id)
        {
            if (ModelState.IsValid)
            {
                booking.RentalDuration = booking.RentalDurationCalculator((DateTime)booking.PickUpDate, (DateTime)booking.DropOffDate);
                booking.rentalTotal = (int)booking.TotalCalculator(id, booking.RentalDuration);

                _dbx.Bookings.Add(booking);
                _dbx.SaveChanges();
            }

            return RedirectToAction("Index");
        }
    }
}

Booking Create视图

@model CarRentals.Models.Booking
@{
    ViewData["Title"] = "创建预订";
}

<div class="row">
    <div class="container mt-5">
        <div class="row">
            <!-- 左侧列 - 车辆图片 -->
            <div class="col-md-4">
                @*<src ="~/images/cars/@Model.Cars.CarImage1" alt="车辆图片" class="img-fluid">*@
            </div>
            <!-- 右侧列 - 预订表单 -->
            <div class="col-md-8">
                <form asp-action="Create" method="post">
                    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                    <div class="form-group text-center">
                        <label asp-for="FullName">全名</label>
                        <input asp-for="FullName" type="text" class="form-control mt-2">
                    </div>
                    <div class="form-group text-center">
                        <label asp-for="Country">国家</label>
                        <input asp-for="Country" type="text" class="form-control mt-2">
                    </div>
                    <div class="form-group text-center">
                        <label asp-for="LicenseNumber">驾照号码</label>
                        <input asp-for="LicenseNumber" type="text" class="form-control mt-2">
                    </div>
                    <div class="form-group text-center">
                        <label asp-for="LicenseIssueCountry">驾照签发国家</label>
                        <input asp-for="LicenseIssueCountry" type="text" class="form-control mt-2">
                    </div>
                    <div class="form-group text-center">
                        <label asp-for="PhoneNumber">电话号码</label>
                        <input asp-for="PhoneNumber" type="text" class="form-control mt-2">
                    </div>
                    <div class="form-group text-center">
                        <label asp-for="Email">邮箱</label>
                        <input asp-for="Email" type="text" class="form-control mt-2">
                    </div>
                    <div class="form-group text-center hidden">
                        <input asp-for="CarId" hidden /> @*value="@Model.Car.Id"*@
                    </div>
                    <div class="form-group text-center">
                        <label asp-for="PickUpDate">取车日期:</label>
                        <input asp-for="PickUpDate" type="date" class="form-control mt-2" placeholder="">
                    </div>
                    <div class="form-group text-center">
                        <label asp-for="DropOffDate">还车日期:</label>
                        <input asp-for="DropOffDate" type="date" class="form-control mt-2" placeholder="">
                    </div>
                    <div class="form-group mt-2 text-center">
                        <a asp-controller="CarList" asp-action="Index" class="btn btn-secondary">返回</a>
                        <input type="submit" value="创建" class="btn btn-success" @*asp-route-Id="@Model.Cars.Id"*@ />
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>

问题修复方案

1. 车辆Id传递问题修复

步骤1:修改Create GET方法,接收并绑定车辆Id

public IActionResult Create(int carId)
{
    Booking booking = new Booking
    {
        CarId = carId // 将传入的车辆Id赋值给Booking的CarId字段
    };
    return View(booking);
}

步骤2:修改Details视图的预订按钮,传递车辆Id

在Details局部视图的“立即预订”按钮添加路由参数:

<a asp-controller="Booking" asp-action="Create" asp-route-carId="@Model.Id" class="btn btn-primary">立即预订</a>

步骤3:激活视图中的CarId隐藏字段

取消视图中CarId隐藏字段的注释,asp-for会自动填充模型中的值:

<div class="form-group text-center hidden">
    <input asp-for="CarId" hidden />
</div>

2. "IDENTITY_INSERT设置为OFF"异常修复

该异常是因为Booking的Id字段为自增主键,但代码中可能手动给Id赋值,数据库拒绝手动插入自增字段值。修复方式:

  • 确保代码中没有手动给Booking.Id赋值(包括控制器、视图、模型构造方法)
  • 确认DbContext中Id字段的自增配置(默认已开启,若被修改需恢复):
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Booking>()
            .Property(b => b.Id)
            .ValueGeneratedOnAdd(); // 强制设置为自增
    }
    

3. 模型其他隐藏问题修复

修正ForeignKey关联错误

Booking模型中Car导航属性的ForeignKey应关联CarId,而非CarTypeId:

public int? CarId { get; set; }
[ForeignKey("CarId")] // 修正关联字段
public virtual Car? Car { get; set; } // 添加set访问器

修正TotalCalculator方法逻辑

当前方法创建空Car对象无法匹配车辆Id,需从数据库查询对应车辆:

// 修改方法,注入DbContext
public double TotalCalculator(int idGiven, double rDuration, ProjectDbContext db)
{
    var car = db.Cars.FirstOrDefault(c => c.Id == idGiven);
    return car == null ? 0 : car.CarPrice * rDuration;
}

在Controller中调用时传入DbContext:

booking.rentalTotal = (int)booking.TotalCalculator(id, booking.RentalDuration, _dbx);

内容的提问来源于stack exchange,提问作者acekensei

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 11:57:11