【问题标题】:Create record using Model List使用模型列表创建记录
【发布时间】:2014-09-30 17:47:51
【问题描述】:

我正在尝试创建发票。我有两个模型,InvoiceInvoiceItems

我可以使用硬编码值插入,但我希望能够使用TextBoxes 即时创建发票。如何使用相同的视图插入一条记录,该记录获取发票数据和发票项目中的动态数据并插入到两个表中?我希望最终有一个 添加更多 按钮,我可以在该按钮上停留在同一页面上并继续将项目添加到同一张发票中。你可以在下面看到我到目前为止所做的尝试。

发票模型:

public class Invoice
{
    [Key]
    public int InvoiceId { get; set; }
    public int ClientId { get; set; }
    [Display(Name = "Amount")]
    public decimal Amount { get; set; }
    [Display(Name = "Invoice Creation Date")]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
    public DateTime CreationDate { get; set; }
    [Display(Name = "Invoice Due Date")]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
    public DateTime DueDate { get; set; }
    [Display(Name = "Notes")]
    public string InvoiceNotes { get; set; }

    public List<InvoiceDetails> InvoiceDetails { get; set; } 
    public List<Clients> Clients { get; set; } 
}

InvoiceItem 模型:

public class InvoiceDetails
{
    [Key]
    public int InvoiceDetailsId { get; set; }
    public int InvoiceId { get; set; }
    [DisplayName("Item Name")]
    public string Name { get; set; }
    [DisplayName("Item Note")]
    public string Note { get; set; }
    [DisplayName("Qty")]
    public decimal? Quantity { get; set; }
    [DisplayName("Rate/Hour")]
    public decimal? Price { get; set; }
    [DisplayName("Item Total")]
    public decimal? Total { get; set; }
}

发票控制器:

private NovaDb _db = new NovaDb();
public ActionResult InvoiceInformation()
    {
        var invoice = new Invoice();

        invoice.InvoiceDetails = new List<InvoiceDetails>();

        return View(invoice);
    }

    [HttpPost]
    public ActionResult InvoiceInformation(Invoice model)
    {
        if (ModelState.IsValid)
        {
            var invoices = new Invoice()
            {
                Amount = model.Amount,
                CreationDate = model.CreationDate,
                DueDate = model.DueDate,
                InvoiceNotes = model.InvoiceNotes,
                InvoiceId = model.InvoiceId,
                ClientId = model.ClientId                    
            };

            _db.Invoices.Add(invoices);
            _db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(model);
    }

发票视图:

@model NovaFinancial.Models.Invoice

@{
ViewBag.Title = "InvoiceInformation";
}

<h2>InvoiceInformation</h2>

@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)

<fieldset>
    <legend>Invoice</legend>

    @Html.HiddenFor(model => model.InvoiceId)

    <div class="editor-label">
        @Html.LabelFor(model => model.ClientId)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.ClientId)
        @Html.ValidationMessageFor(model => model.ClientId)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Amount)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Amount)
        @Html.ValidationMessageFor(model => model.Amount)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.CreationDate)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.CreationDate)
        @Html.ValidationMessageFor(model => model.CreationDate)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.DueDate)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.DueDate)
        @Html.ValidationMessageFor(model => model.DueDate)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.InvoiceNotes)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.InvoiceNotes)
        @Html.ValidationMessageFor(model => model.InvoiceNotes)
    </div>

    <div>
        <table>
            <tr>
                <th>Name</th>
                <th>Notes</th>
                <th>Qty</th>
                <th>Price</th>
                <th>Total</th>
            </tr>
            @for (int i = 0; i < Model.InvoiceDetails.Count; i++)
            {
                @Html.HiddenFor(m=>m.InvoiceDetails[i].Name)    
                @Html.HiddenFor(m=>m.InvoiceDetails[i].Note) 
                @Html.HiddenFor(m=>m.InvoiceDetails[i].Quantity) 
                @Html.HiddenFor(m=>m.InvoiceDetails[i].Price) 
                @Html.HiddenFor(m=>m.InvoiceDetails[i].Total) 
                <tr>
                    <td>@Html.DisplayFor(m=>m.InvoiceDetails[i].Name) | @Html.TextBoxFor(m=>m.InvoiceDetails[i].Name)</td>
                    <td>@Html.DisplayFor(m=>m.InvoiceDetails[i].Note) | @Html.TextBoxFor(m=>m.InvoiceDetails[i].Note)</td>
                    <td>@Html.DisplayFor(m=>m.InvoiceDetails[i].Quantity) | @Html.TextBoxFor(m=>m.InvoiceDetails[i].Quantity)</td>
                    <td>@Html.DisplayFor(m=>m.InvoiceDetails[i].Price) | @Html.TextBoxFor(m=>m.InvoiceDetails[i].Price)</td>
                    <td>@Html.DisplayFor(m=>m.InvoiceDetails[i].Total) | @Html.TextBoxFor(m=>m.InvoiceDetails[i].Total)</td>
                </tr>
            }                
        </table>
    </div>

    <p>
        <input type="submit" value="Save" />
    </p>
</fieldset>
}

【问题讨论】:

  • 那么,你的问题是什么?
  • 只是想检查您是否在问题上取得了任何进展。它让我很感兴趣,所以我今天花了一点时间来研究它。我可以用一个项目创建发票,但仍在试图弄清楚如何让多个项目通过。我确实知道使用相同名称传递表单输入会给一个数组,我觉得它可能包含密钥。

标签: asp.net-mvc razor asp.net-mvc-viewmodel


【解决方案1】:

我想出了一个可能不是最好的“一个”解决方案,但它确实有效。您仍然需要添加代码以使其更健壮,但通用框架已经存在。

在您看来,请保持发票详细信息(名称、数量、价格)的所有文本框的名称属性值相同,但请保持 ID 的唯一性。我使用了一些 jQuery 和 JavaScript 来根据用户单击的按钮的需要生成额外的行。例如,

<input type="text" name="Name" id="Name"> <!--first line item for Item Name-->
<input type="number" name="Quantity" id="Quantity"> <!--first for Quanitity -->

<input type="text" name="Name" id="Name2"> <!--second line item for Item Name-->
<input type="number" name="Quantity" id="Quantity2"> <!-- second for Quanitity -->

InvoiceDetail 行的值将作为逗号分隔的字符串传回服务器(最好确保您的项目名称没有逗号!)。在服务器端,

var Names = Request["Name"]; // this would yield something like "Labor,Parts"

在控制器中,您需要将字符串解析为数组并从中创建 InvoiceDetail 的实例。我编写了一个私有方法来拆分字符串并将 InvoiceDetail 对象列表返回给 action 方法。您有责任验证这些数据:客户端和服务器端都需要验证。

我做了一些实验。您可以在此处查看所有代码:http://mefixme.blogspot.com/2014/10/aspnet-mvc-how-to-add-model-with.html

希望对你有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    相关资源
    最近更新 更多