【问题标题】:Pass jQuery data from View to Controller and save it as many-to-many将 jQuery 数据从 View 传递到 Controller 并将其保存为多对多
【发布时间】: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 参数以匹配模型。

标签: jquery asp.net asp.net-mvc asp.net-core asp.net-mvc-4


【解决方案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,如果原始问题已解决,请接受作为答案。如果有其他问题,请发布一个新线程并分享详细的代码和解释。
猜你喜欢
  • 2019-06-15
  • 2023-01-24
  • 2020-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多