来自 3 个表的 POST 和 GET 值通过多对多关系与 Code First 链接

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

带有多个可选复选框的 Visual Studio Code 中的 Html 表单:

<form name="CarServ" id="myForm">
            <div>
                <label>CarModel:</label>
                <input type="text" id="model" size="65" name="CarModel" placeholder="Enter Car Model" required>
            </div>

            <div class="check">
    
                <label>Addons:</label>
    
                <input type="checkbox" name ="SelectedCheckboxes[]" value="10%off First service visit" id="10%off First service visit">
                <label for="10%off First service visit">10%off First service visit</label>
                <input type="checkbox" name="SelectedCheckboxes[]" value="10%off Waterwash"  id="10%off Waterwash">
                <label for="10%off Waterwash">10%off Waterwash</label>


                <input type="checkbox" name ="SelectedCheckboxes[]" value="Free AC Inspection" id="Free AC Inspection">
                <label for="Free AC Inspection">Free AC Inspection</label>


            </div>  
                    
            <button id="btn" type="submit">Submit</button>
        
    
        </form>

dotnet core api 中的三种模型, CarForm.cs:

public class CarForm
    {
        public int Id { get; set; }
        [Required]
        public string CarModel { get; set; }
        [Required]
        public string SelectedCheckboxes { get; set; }
        public IList<Selection> Selections { get; set; }


    }

插件.cs:

public class Addon
    {
        public int Id { get; set; }
        public string CheckboxName { get; set; }
        public IList<Selection> Selections { get; set; }
    }

Selection.cs:

 public class Selection
    {
        public int CarFormId { get; set; }
        public CarForm CarForms { get; set; }

        public Addon Addons { get; set; }
        public int AddonId { get; set; }

    }

CarDbContext.cs:

    public class CarDbContext : DbContext
    {
        public CarDbContext(DbContextOptions<CarDbContext> options) : base(options)
        {
        }

        public DbSet<CarForm> CarForms { get; set; }
        public DbSet<Addon> Addons { get; set; }
        public DbSet<Selection> Selections { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Selection>()
                .HasKey(s => new { s.CarFormId, s.AddonId });

            modelBuilder.Entity<Addon>().HasData(
                new Addon { Id = 1, CheckboxName = "10%off First service visit" },
                new Addon { Id = 2, CheckboxName = "10%off Waterwash" },
                new Addon { Id = 3, CheckboxName = "Free AC Inspection" });
        } 
    }

创建控制器类:

namespace CarServiceFormApi.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class CarServiceFormController : ControllerBase
    {
        private readonly CarDbContext _context;

        public CarServiceFormController(CarDbContext context)
        {
            _context = context;
        }

        [HttpPost("submit-form")]
        public IActionResult SubmitForm([FromBody] CarForm carForm)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            // Save the CarForm to the database
            _context.CarForms.Add(carForm);
            _context.SaveChanges();

            // Create the selections for the CarForm
            var selections = carForm.SelectedCheckboxes.Select(id => new Selection
            {
                CarFormId = carForm.Id,
                AddonId = id
            });
            _context.Selections.AddRange(selections);
            _context.SaveChanges();

            return Ok();
        }
       
                [HttpGet("get-form-data/{id}")]
                public async Task<IActionResult> GetFormData(int id)
                {
                    // Retrieve the CarForm from the database
                    var carForm = await _context.CarForms.Include(cf => cf.Selections).ThenInclude(s => s.Addons).FirstOrDefaultAsync(cf => cf.Id == id);
                    if (carForm == null)
                    {
                        return NotFound();
                    }

                    // Return the CarForm as JSON
                    return Ok(carForm);
                }
       
    }
}

基本上我想要实现的是,我的 html 表单输入详细信息必须发布到 API 并存储在数据库中。然后,使用 GET 方法,我试图在成功时将数据检索回控制台。由于它是一个多选复选框,我将一组 Selectedcheckboxes 传递给 API 并尝试将其存储在数据库中。

现在当我运行我的 html 表单时,我在控制台上收到一个错误,如

{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"00-d0f3aa9cab0ad5f1450f6bbb403a1a9c-adf3f2910efaeafb-00","errors":{"CarModel":["The CarModel field is required."],"Selections":["The Selections field is required."],"SelectedCheckboxes":["The SelectedCheckboxes field is required."]}}

它显示“选择”字段是必需的!但我还没有在“CarForm.cs”中声明一个选择字段。我希望我的“CarForm.cs”上的选择线是执行链接模型的功能。无法弄清楚我在代码中哪里出错了。

c# entity-framework-core ef-code-first asp.net-core-webapi
2个回答
0
投票

尝试将

SelectedCheckboxes[]
更改为简单的
SelectedCheckboxes
。当后端实际上是单个字符串值时,您正试图绑定一个列表。
Selections
字段与
CarForm
具有循环依赖性。最好创建一个与 DTO 数据库关系不紧密耦合的单独视图模型。


0
投票

基本上我想要实现的是,我的 html 表单输入详细信息 必须发布到 API 并存储在数据库中。然后,使用 GET 方法我试图在成功时将数据检索回控制台

根据您的描述和场景,您的代码片段确实看起来合乎逻辑,即使我不认为它的气味仍然存在,您也在使简单的东西变得嘈杂和笨拙。

为了实现 API 和 HTML 的东西,javascript 可能是理想的选择,但是,它可以在没有它的情况下实现,甚至可以在一般的 MVC 控制器上实现。

除此之外,我认为您的模型设计也是不必要的,因为我们只需要一个插件列表和汽车详细信息,除了不清楚您为什么使用该关系设计之外。

让我们开始行动,我们如何以更简洁的方式完成您的场景:

使用 MVC 控制器:

型号:

如前所述,我需要的只是汽车 mdoel 和插件。因此,我将所有这些修改为 CarFormViewModel。

public class Addon
    {
        public int Id { get; set; }
        public string? CheckboxName { get; set; }
        public bool IsChecked { get; set; }
    }

    public class CarFormViewModel
    {
        public int Id { get; set; }
        public string? CarModel { get; set; }
        public List<Addon>? Addons { get; set; }
    }

控制器:

public IActionResult LoadView()
        {
            var addonsList = new List<Addon>()
            {
                new Addon() { Id=1,CheckboxName="10% off First service visit", IsChecked = false },
                new Addon() { Id=2,CheckboxName="10% off Waterwash", IsChecked = false },
                new Addon() { Id=3,CheckboxName="Free AC Inspection", IsChecked = false },


            };

            var model = new CarFormViewModel();
            model.Addons = addonsList;
            return View(model);
        }

景色:

@model DotNetCoreTestApp.Models.CarFormViewModel
@{
    ViewData["Title"] = "Car  Addons Check Box List";
}

<form asp-action="SubmitCarAddonSelectedValue" asp-controller="Home" method="post">

    <table class="table table-striped table-bordered mr-3 ml-3">

        <tr>
            <th> <label asp-for="CarModel"></label></th>
            <td> <input asp-for="CarModel" class="form-control" placeholder="Enter Car Model" /><span asp-validation-for="CarModel"></span></td>
        </tr>
        <tr>
            <th>Addons:</th>
            <th>
                @for (int i = 0; i < Model.Addons?.Count; i++)
                {
                    <label>@Model.Addons[i].CheckboxName</label>
                    <input asp-for="@Model.Addons[i].IsChecked" />
                    <input type="hidden" asp-for="@Model.Addons[i].Id" />
                    <input type="hidden" asp-for="@Model.Addons[i].CheckboxName" />
                }
            </th>
        </tr>
    </table>
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

提交后操作:

        [HttpPost]
        public IActionResult SubmitCarAddonSelectedValue(CarFormViewModel carFormViewModel)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var selectedAddonsValueFromView = carFormViewModel.Addons?.Where(selectedAddons => selectedAddons.IsChecked == true).ToList();
            //Insert your addons in database

            return Ok(selectedAddonsValueFromView);
        }

输出:

使用 API 控制器:

景色:

在视图中只需要改变这种格式的 API 路由 URL [email protected]("SubmitForm","CarServiceForm") 如下:

@model DotNetCoreTestApp.Data.CarFormViewModel
@{
    ViewData["Title"] = "Combatant Check Box List";
}

<form id="SubmitForm" method="post" [email protected]("SubmitForm","CarServiceForm")>

    <table class="table table-striped table-bordered mr-3 ml-3">

        <tr>
            <th> <label asp-for="CarModel"></label></th>
            <td> <input asp-for="CarModel" class="form-control" placeholder="Enter Car Model" /><span asp-validation-for="CarModel"></span></td>
        </tr>
        <tr>
            <th>Addons:</th>
            <th>
                @for (int i = 0; i < Model.Addons?.Count; i++)
                {
                    <label>@Model.Addons[i].CheckboxName</label>
                    <input asp-for="@Model.Addons[i].IsChecked" />
                    <input type="hidden" asp-for="@Model.Addons[i].Id" />
                    <input type="hidden" asp-for="@Model.Addons[i].CheckboxName" />
                }
            </th>
        </tr>
    </table>
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

API控制器:

        [HttpPost("SubmitForm")]
        public IActionResult SubmitForm([FromForm] CarFormViewModel carFormViewModel)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            //Get Car Details
            var carDetails = carFormViewModel.CarModel;

            //Get Addons Details
            var selectedAddonsValueFromView = carFormViewModel.Addons?.Where(selectedAddons => selectedAddons.IsChecked == true).ToList();
           
            //Do whatever you want to do in database

           

            return Ok(carFormViewModel);
 
        }

输出:

注意:如果您想知道如何实现使用javascript您可以在这里查看我们的官方文档

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