将 jQuery 数据从 View 传递到 Controller 并将其保存为多对多

Posted

技术标签:

【中文标题】将 jQuery 数据从 View 传递到 Controller 并将其保存为多对多【英文标题】:Pass jQuery data from View to Controller and save it as many-to-many 【发布时间】:2021-09-27 14:14:19 【问题描述】:

我有一个多对多的关系。我从 asp.net 3.0 和 ef core 3.1 中的脚手架为以下 2 个实体(产品和发票)生成了控制器和视图

我能够从这两个实体进行 CRUD。

在“发票视图”页面中,我需要一个从 Product 表提供的下拉列表,并将 ItemName 添加到下拉列表中。 我已经通过 ViewData["Products"] 做到了,而且效果很好。

当用户从该下拉列表中进行选择时,旁边会出现一个“添加项目”按钮, 如果用户单击该“添加项目”按钮,则必须在页面下方添加项目名称。我已经通过 jquery 及其作品做到了

页面底部有一个保存按钮,点击后,它只会通过绑定将发票模型传递给控制器​​(这是正确的行为), 但我不确定如何将所有添加的项目(仅它们的 Id)传递给控制器​​以保存在连接表(ProductInvoice)中。

不确定也许我没有正确设计应用程序的架构,这就是我编写整个场景/用例的原因也许你可以建议我重新设计。

简而言之,用例是:用户必须将 itemName(从 Product 表中获取)添加到发票并将其保存为多对多关系。

**如何保存我在 Invoice 页面上添加的所有 ItemId,将它们以多对多的方式保存到 ProductInvoice 表中,

如何将它们从视图传递给控制器​​?**

我搜索了一整天,我找不到怎么做,这就是我发帖的原因。

public class Product

    public int ProductId  get; set; 
    public int Price  get; set; 
    public string ItemName  get; set;     
    public IList<ProductInvoice> ProductInvoices  get; set; 


public class Invoice

    public int InvoiceId  get; set; 
    public DateTime InvoiceDate  get; set; 
    public IList<ProductInvoice> ProductInvoices  get; set; 

    
public class ProductInvoice

    [Key]
    public int ProductId  get; set; 
    public Product Product  get; set; 

    [Key]
    public int InvoiceId  get; set; 
    public Invoice Invoice  get; set; 


[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("InvoiceId,InvoiceDate")] Invoice invoice)

    if (ModelState.IsValid)
    
        _context.Add(invoice);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    
    return View(invoice);



<script>
        $(document).ready(function () 

            var totalInvoice = 0;

            $("#btn-add-item").click(function () 

                var selectedItem = $('#SelectedProducts :selected').text();
                var getCostPerItem = $('#SelectedProducts :selected').val();

                getCostPerItem = getCostPerItem.split("-")[1];
                getCostPerItem = getCostPerItem.split(".")[0];
                totalInvoice = parseInt(totalInvoice) + parseInt(getCostPerItem);

                $('<div id="created_div">' + '<b>+</b> ' + selectedItem + ' :  $ ' + ' ' + getCostPerItem + '<a href="#" class="btn btn-danger btn-sm btn-remove-item float-right">Remove</a></div><br>').insertAfter('#main-body-card');
                $("#total-invoice-input").val(totalInvoice);
            );
        );
    </script>

【问题讨论】:

嗨@CodingValue,请分享您的整个剃须刀视图。另外,你的Invoice 模型中没有CreatedDateCreateByUserTotalInvoice这样的模型,所以模型绑定系统不会成功。 @Rena 我修改了 Create 参数以匹配模型。 【参考方案1】:

这是一个完整的工作演示,您可以关注:

型号:

public class Product

    public int ProductId  get; set; 
    public int Price  get; set; 
    public string ItemName  get; set; 
    public IList<ProductInvoice> ProductInvoices  get; set; 


public class Invoice

    public int InvoiceId  get; set; 
    public DateTime InvoiceDate  get; set; 
    public IList<ProductInvoice> ProductInvoices  get; set; 


public class ProductInvoice

    [Key]
    public int ProductId  get; set; 
    public Product Product  get; set; 

    [Key]
    public int InvoiceId  get; set; 
    public Invoice Invoice  get; set; 

查看:

首先,在我的项目中,产品下拉列表值是ProductId,文本是ItemName

然后,要传递相关的ProductId 并添加到Invoice 模型中,您需要添加隐藏(或不隐藏)输入,其名称类似于:ProductInvoices[index].ProductId

最后,Bind 属性([Bind("InvoiceId,CreatedDate,CreateByUser,TotalInvoice")]) 中的参数必须与模型Invoice 匹配。

@model Invoice    
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div id="main-body-card"></div>
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="InvoiceDate" class="control-label"></label>
                <input asp-for="InvoiceDate" class="form-control" />
                <span asp-validation-for="InvoiceDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <select id="SelectedProducts"  asp-items="(SelectList)@ViewData["Products"]"></select>
                <button type="button" id="btn-add-item">Add</button>
            </div>
            <label>total: </label><input id="total-invoice-input" />
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>      
@section Scripts

    <script>
        $(document).ready(function () 
            var totalInvoice = 0;
            var i = 0;      //add this...
            $("#btn-add-item").click(function ()     
                var selectedItem = $('#SelectedProducts :selected').text();
                var getCostPerItem = $('#SelectedProducts :selected').val();            
                totalInvoice = parseInt(totalInvoice) + parseInt(getCostPerItem);   
                $('<div id="created_div">' + '<b>+</b> ' + selectedItem + ' :  $ ' + ' ' + getCostPerItem + '<a href="#" class="btn btn-danger btn-sm btn-remove-item float-right">Remove</a></div><br>').insertAfter('#main-body-card');
                //add this....
                $("<input value='"+getCostPerItem+"' name='ProductInvoices[" + i + "].ProductId' hidden/>").insertAfter('#created_div');
                $("#total-invoice-input").val(totalInvoice);
                i++;   //add this...
            );
        );
    </script>

控制器:

public IActionResult Create()

    ViewData["Products"] = new SelectList(_context.Product.ToList(), "ProductId", "ItemName");
    return View();

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("InvoiceId,InvoiceDate,ProductInvoices")] Invoice invoice)

    if (ModelState.IsValid)
    
        _context.Add(invoice);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    
    return View(invoice);

结果:

【讨论】:

感谢您的帮助。我的代码工作正常。我被困在:如何保存我在发票页面上添加的所有 ItemId,将它们以多对多的形式保存到 ProductInvoice 表中?如何将它们(所有 ItemId)从视图传递到控制器,以便在 ProductInvoice 中以多对多的形式保存。我能够正确保存 Invoice,但它不保存 ProductInvoice (ProductId, InvoiceId)。 嗨@CodingValue,请检查我的代码。将它们以多对多的形式保存到 ProductInvoice 表中效果很好。 谢谢。让我看看,很快就会回复您。 同时,如何将 3 个值(产品模型)从控制器(Create 方法)传递到 SelectList(Dropdownlist)?因为 SelectList 只能接受 2(值和文本) 嗨@CodingValue,如果原始问题已解决,请接受作为答案。如果有其他问题,请发布一个新线程并分享详细的代码和解释。

以上是关于将 jQuery 数据从 View 传递到 Controller 并将其保存为多对多的主要内容,如果未能解决你的问题,请参考以下文章

将数据从 Table View Cell 传递到 IOS 中的 View Controller

使用委托将数据从Collection View Controller传递到View Controller

将核心数据对象从 DetailViewController 传递到另一个 View Controller

如何使用 ajax get 将数据从 View 传递到 Controller 或使用参数在 mvc 中发布

使用DAO将值从java类传递给jsp页面

如何将 CloudKit 记录数据从“TableView-Controller B”传递到“View-Controller C”?