如何在单页提交表单时保存发票标题和发票行项目,使用.NET Core Razor Pages?

huangapple go评论110阅读模式
英文:

How to save Invoice Header and invoice rows on single page submit form with .net core razor pages?

问题

1.Explanation

我想打开“创建”页面,填写发票头数据,填写发票动态行数据,并一次性保存所有内容。

(* 更新的代码)
我成功解决了RowList错误,它不允许我添加多行:
https://stackoverflow.com/questions/75716824/how-to-insert-multiple-rows-with-addrange-in-asp-net-core-razor-pages/75717334#75717334

现在我遇到一个错误

1.1 错误

ArgumentNullException: 值不能为空。(参数 'source')

System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)

ArgumentNullException: 值不能为空。(参数 'source')

System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
System.Linq.Enumerable.Count(IEnumerable source)
EPIDENT5.Pages.Magazina.Pages_Magazina_Create.b__28_0() in Create.cshtml
...

@for (int i = 0; i < Model.RowList.Count(); i++)

Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.GetChildContentAsync(bool useCachedResult, HtmlEncoder encoder)
Microsoft.AspNetCore.Mvc.TagHelpers.RenderAtEndOfFormTagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output)
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.g__Awaited|0_0(Task task, TagHelperExecutionContext executionContext, int i, int count)
EPIDENT5.Pages.Magazina.Pages_Magazina_Create.ExecuteAsync() in Create.cshtml

ViewData["Title"] = "Create";

我知道我遗漏了一些东西,但不明白问题出在哪里。

2.问题

如何完成这个操作?

3.前端代码:

// 这是头部表格

<table class="table table-striped border-0"
       style="width: 100%; text-align: left;">
    <thead class="border-0">
        <tr class="border-0">
            <td class="border-0" style="min-width:100%;">
                <div class="border border-secondary p-4">
                    <div class="row ">
                        <div style="float:left;width:50%;">
                            <div class="form-group m-1">
                                <label asp-for="InvHeader.Cli" class="control-label" style="font-size:80%;">Client</label>
                                <input asp-for="InvHeader.Cli" class="form-control" value="客户名称" />
                            </div>
                        </div>
                        <div style="float:left;width:25%;">
                            <div class="form-group m-1">
                                <input asp-for="InvHeader.InvDate" class="form-control" type="date" value="@(DateTime.UtcNow.Date.ToString("yyyy-MM-dd"))" />
                                <span asp-validation-for="InvHeader.InvDate" class="text-danger"></span>
                            </div>
                        </div>
                        <div style="float:left;width:25%;">
                            <div class="form-group m-1">
                                <input asp-for="InvHeader.InvNr" class="form-control" value="33" />
                                <span asp-validation-for="InvHeader.InvNr" class="text-danger"></span>
                            </div>
                        </div>
                    </div>
                </div>
            </td>
        </tr>
    </thead>
</table>

// 这是动态行表格

<table id="table1" border="0">
    <tr style="font-size:80%;">
        <th style="width:50%;">产品</th>
        <th style="width:5%;">数量</th>
        <th style="width:5%;">价格</th>
    </tr>
    @foreach (var item in Model.PL)
    {
        <tr class="border-bottom">
            <td>
                <select id="Products" asp-for="@Model.PL[@i].ProdId" class="form-control" type="text" name="data[@i][ProdId]" style="width:100%">
                    @foreach (var item in Model.PL)
                    {
                        <option value="@item.ProdId"
                                qty="@qty"
                                price="@Convert.ToInt32(item.price)">@item.name, @Convert.ToInt32(item.price)</option>
                    }
                </select>
            </td>
            <td><input asp-for="@Model.MR[@i].qty" class="form-control" type="text" name="qty[@i]" style="width:100%" /></td>
            <td><input asp-for="@Model.MR[@i].price" class="form-control" type="text" name="price[@i]" style="width:100%" /></td>
        </tr>
    }
</table>

4.后端代码

// 数据绑定部分

[BindProperty]
public InvHeader InvHeader { get; set; } = default!;
public IList RowList { get; set; }

// Onget 方法,其中获取行数

public IActionResult OnGetAsync()
{
var rr = new List()
{
new InvRow() { Name = "Apple", Qty = 5, Price = 100 },
new InvRow() { Name = "Peach", Qty = 3, Price = 500 },
new InvRow() { Name = "Ananas", Qty = 1, Price = 1100 },
};

RowList = rr;

return Page();

}

// Onpost 方法

public async Task OnPostAsync(IList RowList)
{
if (!ModelState.IsValid)
{
return Page();
}

_context.InvHeaders.Add(InvHeader);

await _context.InvRows.AddRangeAsync(RowList);

await _context.SaveChangesAsync();

return RedirectToPage("./Index");

}

英文:

1.Explaination

I want to open the "Create" page, fill the invoice header data, fill the invoice dynamic rows data and save everything on one single submit.

(* Updated code)
I managed to solve the RowList error, which did not let me add multiple rows:

https://stackoverflow.com/questions/75716824/how-to-insert-multiple-rows-with-addrange-in-asp-net-core-razor-pages/75717334#75717334

Now i am getting an error

1.1 The error

ArgumentNullException: Value cannot be null. (Parameter 'source')

System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)

ArgumentNullException: Value cannot be null. (Parameter 'source')

System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
System.Linq.Enumerable.Count&lt;TSource&gt;(IEnumerable&lt;TSource&gt; source)
EPIDENT5.Pages.Magazina.Pages_Magazina_Create.&lt;ExecuteAsync&gt;b__28_0() in Create.cshtml

...

                @for (int i = 0; i &lt; Model.RowList.Count(); i++)

Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.GetChildContentAsync(bool useCachedResult, HtmlEncoder encoder)
Microsoft.AspNetCore.Mvc.TagHelpers.RenderAtEndOfFormTagHelper.ProcessAsync(TagHelperContext context, TagHelperOutput output)
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.<RunAsync>g__Awaited|0_0(Task task, TagHelperExecutionContext executionContext, int i, int count)
EPIDENT5.Pages.Magazina.Pages_Magazina_Create.ExecuteAsync() in Create.cshtml

    ViewData[&quot;Title&quot;] = &quot;Create&quot;;

I know i am missing something but can not understand where the problem is.

2.Question

How can this be done?

3. The frontend code:

&lt;form method=&quot;post&quot;&gt;
                &lt;div asp-validation-summary=&quot;ModelOnly&quot; class=&quot;text-danger&quot;&gt;&lt;/div&gt;


// This is the header table 



                &lt;table class=&quot;table table-striped border-0&quot;
                       style=&quot;width: 100%; text-align: left;&quot;&gt;
                    &lt;thead class=&quot;border-0&quot;&gt;

 &lt;tr class=&quot;border-0&quot;&gt;
                    &lt;td class=&quot;border-0&quot; style=&quot;min-width:100%;&quot;&gt;
                        &lt;div class=&quot;border border-secondary p-4&quot;&gt;
                            &lt;div class=&quot;row &quot;&gt;
                                &lt;div style=&quot;float:left;width:50%;&quot;&gt;
                                    &lt;div class=&quot;form-group m-1&quot;&gt;
                                        &lt;label asp-for=&quot;InvHeader.Cli&quot; class=&quot;control-label&quot; style=&quot;font-size:80%;&quot;&gt;Client&lt;/label&gt;
                                        &lt;input asp-for=&quot;InvHeader.Cli&quot; class=&quot;form-control&quot; value=&quot;clients name&quot; /&gt;
                                    &lt;/div&gt;
                                &lt;/div&gt;
                                &lt;div style=&quot;float:left;width:25%;&quot;&gt;
                                    &lt;div class=&quot;form-group m-1&quot;&gt;
                                        &lt;input asp-for=&quot;InvHeader.InvDate&quot; class=&quot;form-control&quot; type=&quot;date&quot; value=&quot;@(DateTime.UtcNow.Date.ToString(&quot;yyyy-MM-dd&quot;))&quot; /&gt;
                                        &lt;span asp-validation-for=&quot;InvHeader.InvDate&quot; class=&quot;text-danger&quot;&gt;&lt;/span&gt;
                                    &lt;/div&gt;
                                &lt;/div&gt;
                                &lt;div style=&quot;float:left;width:25%;&quot;&gt;
                                    &lt;div class=&quot;form-group m-1&quot;&gt;
                                        &lt;input asp-for=&quot;InvHeader.InvNr&quot; class=&quot;form-control&quot; value=&quot;33&quot; /&gt;
                                        &lt;span asp-validation-for=&quot;InvHeader.InvNr&quot; class=&quot;text-danger&quot;&gt;&lt;/span&gt;
                                    &lt;/div&gt;
                                &lt;/div&gt;
                            &lt;/div&gt;
                        &lt;/div&gt;
                    &lt;/td&gt;
                &lt;/tr&gt;
                    &lt;/thead&gt;
                &lt;/table&gt;



//This is the dynamic rows table



 &lt;table id=&quot;table1&quot; border=&quot;0&quot;&gt;
            &lt;tr style=&quot;font-size:80%;&quot;&gt;                  
                &lt;th style=&quot;width:50%;&quot;&gt;Product&lt;/th&gt;
                &lt;th style=&quot;width:5%;&quot;&gt;qty&lt;/th&gt;
                &lt;th style=&quot;width:5%;&quot;&gt;price&lt;/th&gt;
            &lt;/tr&gt;
                        foreach (var item in Model.PL)
                {
                    &lt;tr class=&quot;border-bottom&quot;&gt;                           
                        &lt;td&gt;
                            &lt;select id=&quot;Products&quot; asp-for=&quot;@Model.PL[@i].ProdId&quot; class=&quot;form-control&quot; type=&quot;text&quot; name=&quot;data[@i][ProdId]&quot; style=&quot;width:100%;&quot;    &gt;
                              
                                @foreach (var item in Model.PL)
                                {
                                    &lt;option    value=&quot;@item.ProdId&quot;    
                                            qty=&quot;@qty&quot;
                                        price=&quot;@Convert.ToInt32(item.price)&quot;&gt;@item.name,   @Convert.ToInt32(item.price)&lt;/option&gt;
                                }
                            &lt;/select&gt;
                        &lt;/td&gt;
						&lt;td&gt;&lt;input asp-for=&quot;@Model.MR[@i].qty&quot; class=&quot;form-control&quot; type=&quot;text&quot; name=&quot;qty[@i]&quot; style=&quot;width:100%;&quot; /&gt;&lt;/td&gt;
                                &lt;td&gt;&lt;input asp-for=&quot;@Model.MR[@i].price&quot; class=&quot;form-control&quot; type=&quot;text&quot; name=&quot;price[@i]&quot; style=&quot;width:100%;&quot; /&gt;&lt;/td&gt;
                     &lt;/tr&gt;
					 &lt;/table&gt;
					 
					 &lt;/form&gt;

4.The backend code

//The data binding part

 [BindProperty]
    public InvHeader InvHeader { get; set; } = default!;
    public IList&lt;InvRow&gt; RowList { get; set; }

//The onget method, where row count id red

 public IActionResult OnGetAsync()
    {

        var rr = new List&lt;InvRow&gt;()
        {
            new InvRow() { Name = &quot;Apple&quot;, Qty = 5, Price = 100 },
             new InvRow() { Name = &quot;Peach&quot;, Qty = 3, Price = 500 },
              new InvRow() { Name = &quot;Ananas&quot;, Qty = 1, Price = 1100 },
        };

        RowList = rr;

        return Page();
    }

//The Onpost method

public async Task&lt;IActionResult&gt; OnPostAsync(IList&lt;InvRow&gt; RowList)
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

         _context.InvHeaders.Add(InvHeader);

        await _context.InvRows.AddRangeAsync(RowList);

        await _context.SaveChangesAsync();

        return RedirectToPage(&quot;./Index&quot;);
    }

答案1

得分: 1

模型绑定通过名称属性绑定属性。与参数匹配的正确名称属性应该是这样的:addrows[index].propertyName

不确定您页面中的 PL 是什么,但似乎只有 qtyprice 输入与 InvRows 模型相关。您需要更改两个输入的名称,如下所示:

<td><input asp-for="@Model.MR[@i].qty" class="form-control" type="text" name="addrows[@i].qty" style="width:100%;" /></td>
<td><input asp-for="@Model.MR[@i].price" class="form-control" type="text" name="addrows[@i].price" style="width:100%;" /></td>

如果选择元素也与 InvRows 模型相关,只需更改选择的名称,如:addrows[@i].ProdId。无论如何,名称取决于您的模型是什么样子。

另外,您的页面包含重复的 foreach,具有相同的名称,这是不正确的。假设应该是:

@for(int i = 0; i < Model.PL.Count(); i++)
{
    <tr class="border-bottom">
        <!-- ... 省略其余内容 ... -->
    </tr>
}

整个工作演示您可以参考:

// Model
public class InvHeaders
{
    // ... 省略其余内容 ...
}
public class InvRows 
{
    // ... 省略其余内容 ...
}
public class Product
{
    // ... 省略其余内容 ...
}

// Page
@page
@model IndexModel

<form method="post">
    <!-- ... 省略其余内容 ... -->
</form>

// PageModel
public class IndexModel : PageModel
{
    [BindProperty]
    public InvHeaders InvHeader { get; set; } = default!;
    [BindProperty]
    public InvRows InvRow { get; set; } = default!;
    public IList<InvRows> MR { get; set; } = default!;
    public List<Product> PL { get; set; }

    // ... 省略其余内容 ...
}

只是一个注意,下面的默认 option 元素中没有 qtyprice 属性,不确定您想要做什么,但我需要提醒您这对模型绑定没有意义:

<option value="@item.ProdId" qty="@qty" price="@Convert.ToInt32(item.Price)">@item.name,   @Convert.ToInt32(item.price)</option>
英文:

Model Binding binds the property by name attribute. The correct name attribute which matches the parameter should be like:addrows[index].propertyName.

Not sure what is your PL in your page, but it seems only qty and price input are related to the InvRows model. You need change the two inputs name like below:

&lt;td&gt;&lt;input asp-for=&quot;@Model.MR[@i].qty&quot; class=&quot;form-control&quot; type=&quot;text&quot; name=&quot;addrows[@i].qty&quot; style=&quot;width:100%;&quot; /&gt;&lt;/td&gt;
&lt;td&gt;&lt;input asp-for=&quot;@Model.MR[@i].price&quot; class=&quot;form-control&quot; type=&quot;text&quot; name=&quot;addrows[@i].price&quot; style=&quot;width:100%;&quot; /&gt;&lt;/td&gt;

If the select element is also related to the InvRows model, just change the select name like: addrows[@i].ProdId. Any way, the name depends on how is your model like.

Besides, your page contains duplicated foreach with same name, it is not correct. Assume that is should be:

@for(int i = 0;i&lt;Model.PL.Count();i++)
{
        
&lt;tr class=&quot;border-bottom&quot;&gt;
    &lt;td&gt;
        &lt;select id=&quot;Products&quot; asp-for=&quot;@Model.PL[@i].ProdId&quot; class=&quot;form-control&quot; type=&quot;text&quot; name=&quot;data[@i][ProdId]&quot; style=&quot;width:100%;&quot;&gt;

            @foreach (var item in Model.PL)
            {
                &lt;option value=&quot;@item.ProdId&quot;&gt;@item.name,   @Convert.ToInt32(item.price)&lt;/option&gt;
            }
        &lt;/select&gt;
    &lt;/td&gt;
    &lt;td&gt;&lt;input asp-for=&quot;@Model.MR[@i].qty&quot; class=&quot;form-control&quot; type=&quot;text&quot; name=&quot;addrows[@i].qty&quot; style=&quot;width:100%;&quot; /&gt;&lt;/td&gt;
    &lt;td&gt;&lt;input asp-for=&quot;@Model.MR[@i].price&quot; class=&quot;form-control&quot; type=&quot;text&quot; name=&quot;addrows[@i].price&quot; style=&quot;width:100%;&quot; /&gt;&lt;/td&gt;
&lt;/tr&gt;
}

A whole working demo you could follow:

Model

public class InvHeaders
{
    public int CliId { get; set; }
    public DateTime InvDate { get; set; }
    public string InvNr { get; set; }
}
public class InvRows 
{
    public int qty { get; set; }
    public int price { get; set; }
}
public class Product
{
    public int ProdId { get; set; }
    public string name { get; set; }
    public int price { get; set; }
}

Page

@page
@model IndexModel

&lt;form method=&quot;post&quot;&gt;
    &lt;div asp-validation-summary=&quot;ModelOnly&quot; class=&quot;text-danger&quot;&gt;&lt;/div&gt;
    &lt;table class=&quot;table table-striped border-0&quot;
           style=&quot;width: 100%; text-align: left;&quot;&gt;
        &lt;thead class=&quot;border-0&quot;&gt;
            &lt;tr class=&quot;border-0&quot;&gt;
                &lt;td class=&quot;border-0&quot; style=&quot;min-width:100%;&quot;&gt;
                    &lt;div class=&quot;border border-secondary p-4&quot;&gt;
                        &lt;div class=&quot;row &quot;&gt;
                            &lt;div style=&quot;float:left;width:25%;&quot;&gt;
                                &lt;div class=&quot;form-group m-1&quot;&gt;
                                    &lt;label asp-for=&quot;InvHeader.CliId&quot; class=&quot;control-label&quot; style=&quot;font-size:80%;&quot;&gt;Client&lt;/label&gt;
                                    &lt;select asp-for=&quot;InvHeader.CliId&quot; class=&quot;form-control font-weight-bold text-primary&quot; asp-items=&quot;ViewBag.FurId&quot;&gt;&lt;/select&gt;
                                &lt;/div&gt;
                            &lt;/div&gt;
                            &lt;div style=&quot;float:left;width:25%;&quot;&gt;
                                &lt;div class=&quot;form-group m-1&quot;&gt;
                                    &lt;input asp-for=&quot;InvHeader.InvDate&quot; class=&quot;form-control&quot; type=&quot;date&quot; value=&quot;@(DateTime.UtcNow.Date.ToString(&quot;yyyy-MM-dd&quot;))&quot; /&gt;
                                    &lt;span asp-validation-for=&quot;InvHeader.InvDate&quot; class=&quot;text-danger&quot;&gt;&lt;/span&gt;
                                &lt;/div&gt;
                            &lt;/div&gt;
                            &lt;div style=&quot;float:left;width:25%;&quot;&gt;
                                &lt;div class=&quot;form-group m-1&quot;&gt;
                                    &lt;input asp-for=&quot;InvHeader.InvNr&quot; class=&quot;form-control&quot; value=&quot;&quot; /&gt;
                                    &lt;span asp-validation-for=&quot;InvHeader.InvNr&quot; class=&quot;text-danger&quot;&gt;&lt;/span&gt;
                                &lt;/div&gt;
                            &lt;/div&gt;
                        &lt;/div&gt;
                    &lt;/div&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
        &lt;/thead&gt;
    &lt;/table&gt;
    &lt;table id=&quot;table1&quot; border=&quot;0&quot;&gt;
        &lt;tr style=&quot;font-size:80%;&quot;&gt;
            &lt;th style=&quot;width:50%;&quot;&gt;Product&lt;/th&gt;
            &lt;th style=&quot;width:5%;&quot;&gt;qty&lt;/th&gt;
            &lt;th style=&quot;width:5%;&quot;&gt;price&lt;/th&gt;
        &lt;/tr&gt;
       
        @for(int i = 0;i&lt;Model.PL.Count();i++)
        {
            
        &lt;tr class=&quot;border-bottom&quot;&gt;
            &lt;td&gt;
                &lt;select id=&quot;Products&quot; asp-for=&quot;@Model.PL[@i].ProdId&quot; class=&quot;form-control&quot; type=&quot;text&quot; name=&quot;data[@i][ProdId]&quot; style=&quot;width:100%;&quot;&gt;

                    @foreach (var item in Model.PL)
                    {
                        &lt;option value=&quot;@item.ProdId&quot;&gt;@item.name,   @Convert.ToInt32(item.price)&lt;/option&gt;
                    }
                &lt;/select&gt;
            &lt;/td&gt;
            &lt;td&gt;&lt;input asp-for=&quot;@Model.MR[@i].qty&quot; class=&quot;form-control&quot; type=&quot;text&quot; name=&quot;addrows[@i].qty&quot; style=&quot;width:100%;&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;input asp-for=&quot;@Model.MR[@i].price&quot; class=&quot;form-control&quot; type=&quot;text&quot; name=&quot;addrows[@i].price&quot; style=&quot;width:100%;&quot; /&gt;&lt;/td&gt;
        &lt;/tr&gt;
        }
    &lt;/table&gt;
    &lt;input type=&quot;submit&quot; value=&quot;POST&quot; /&gt;
&lt;/form&gt;

PageModel

public class IndexModel : PageModel
{
    [BindProperty]
    public InvHeaders InvHeader { get; set; } = default!;
    [BindProperty]
    public InvRows InvRow { get; set; } = default!;
    public IList&lt;InvRows&gt; MR { get; set; } = default!;
    public List&lt;Product&gt; PL { get; set; }

    public void OnGet()
    {   
        //hard-coded the value is just for easy testing
        PL = new List&lt;Product&gt;()
        {
            new Product(){ProdId=1,name=&quot;aa&quot;,price=12},
            new Product(){ProdId=2,name=&quot;bb&quot;,price=16},
            new Product(){ProdId=3,name=&quot;cc&quot;,price=21}
        };
    }
    public void OnPost(List&lt;InvRows&gt; addrows)
    {
         //do your stuff....
    }
}

Just a note, there is no qty or price attribute in default option element below, not sure what do you want to do but I need remind you that it makes no sense for model binding.

&lt;option value=&quot;@item.ProdId&quot; qty=&quot;@qty&quot; price=&quot;@Convert.ToInt32(item. Price)&quot;&gt;

答案2

得分: 0

这是对我有效的部分:

1. 这是前端代码

<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>

    <table class="table table-striped border-0" style="width: 100%; text-align: left;">
        <thead class="border-0">
            <tr class="border-0">
                <td class="border-0" style="min-width:100%;">
                    <div class="border border-secondary p-4">
                        <div class="row ">
                            <div style="float:left;width:50%;">
                                <div class="form-group m-1">
                                    <label asp-for="InvHeader.Cli" class="control-label" style="font-size:80%;">客户</label>
                                    <input asp-for="InvHeader.Cli" class="form-control" value="客户名称" />
                                </div>
                            </div>
                            <div style="float:left;width:25%;">
                                <div class="form-group m-1">
                                    <label asp-for="InvHeader.Cli" class="control-label" style="font-size:80%;">日期</label>
                                    <input asp-for="InvHeader.InvDate" class="form-control" type="date" value="@(DateTime.UtcNow.Date.ToString("yyyy-MM-dd"))" />
                                    <span asp-validation-for="InvHeader.InvDate" class="text-danger"></span>
                                </div>
                            </div>
                            <div style="float:left;width:25%;">
                                <div class="form-group m-1">
                                    <label asp-for="InvHeader.Cli" class="control-label" style="font-size:80%;">编号</label>
                                    <input asp-for="InvHeader.InvNr" class="form-control" value="33" />
                                    <span asp-validation-for="InvHeader.InvNr" class="text-danger"></span>
                                </div>
                            </div>
                        </div>
                    </div>
                </td>
            </tr>
        </thead>
    </table>

    <table id="table1" border="0">
        <tr style="font-size:80%;">
            <th style="width:50%;">名称</th>
            <th style="width:5%;">数量</th>
            <th style="width:5%;">价格</th>
        </tr>

        @for (int i = 0; i < Model.RowList.Count(); i++)
        {
            <tr class="border-bottom">
                <td>
                    <div class="form-group">
                        <input asp-for="@Model.RowList[@i].Name" class="form-control" name="RowList[@i].Name" />
                        <span asp-validation-for="@Model.RowList[@i].Name" class="text-danger"></span>
                    </div>
                </td>
                <td>
                    <div class="form-group">
                        <input asp-for="@Model.RowList[@i].Qty" class="form-control" name="RowList[@i].Qty" value="1" />
                        <span asp-validation-for="@Model.RowList[@i].Qty" class="text-danger"></span>
                    </div>
                </td>
                <td>
                    <div class="form-group">
                        <input asp-for="@Model.RowList[@i].Price" class="form-control" name="RowList[@i].Price" value="33" />
                        <span asp-validation-for="@Model.RowList[@i].Price" class="text-danger"></span>
                    </div>
                </td>
            </tr>
        }
    </table>

    <div class="form-group">
        <input type="submit" value="创建" class="btn btn-primary" />
        <a asp-page="Index">返回列表</a>
    </div>
</form>

2. 这是后端代码

[BindProperty]
public InvHeader InvHeader { get; set; } = default!;
public IList<InvRow> RowList { get; set; }

public IActionResult OnGetAsync()
{
    var rr = new List<InvRow>()
    {
        new InvRow() { Name = "苹果", Qty = 5, Price = 100 },
        new InvRow() { Name = "桃子", Qty = 3, Price = 500 },
        new InvRow() { Name = "菠萝", Qty = 1, Price = 1100 },
    };

    RowList = rr;

    return Page();
}

public async Task<IActionResult> OnPostAsync(IList<InvRow> RowList)
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.InvHeaders.Add(InvHeader);
    await _context.InvRows.AddRangeAsync(RowList);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}
英文:

This what worked for me:

1. This is the frontend code

 &lt;form method=&quot;post&quot;&gt;
&lt;div asp-validation-summary=&quot;ModelOnly&quot; class=&quot;text-danger&quot;&gt;&lt;/div&gt;
&lt;table class=&quot;table table-striped border-0&quot;
style=&quot;width: 100%; text-align: left;&quot;&gt;
&lt;thead class=&quot;border-0&quot;&gt;
&lt;tr class=&quot;border-0&quot;&gt;
&lt;td class=&quot;border-0&quot; style=&quot;min-width:100%;&quot;&gt;
&lt;div class=&quot;border border-secondary p-4&quot;&gt;
&lt;div class=&quot;row &quot;&gt;
&lt;div style=&quot;float:left;width:50%;&quot;&gt;
&lt;div class=&quot;form-group m-1&quot;&gt;
&lt;label asp-for=&quot;InvHeader.Cli&quot; class=&quot;control-label&quot; style=&quot;font-size:80%;&quot;&gt;Client&lt;/label&gt;
&lt;input asp-for=&quot;InvHeader.Cli&quot; class=&quot;form-control&quot; value=&quot;clients name&quot; /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;float:left;width:25%;&quot;&gt;
&lt;div class=&quot;form-group m-1&quot;&gt;
&lt;label asp-for=&quot;InvHeader.Cli&quot; class=&quot;control-label&quot; style=&quot;font-size:80%;&quot;&gt;Date&lt;/label&gt;
&lt;input asp-for=&quot;InvHeader.InvDate&quot; class=&quot;form-control&quot; type=&quot;date&quot; value=&quot;@(DateTime.UtcNow.Date.ToString(&quot;yyyy-MM-dd&quot;))&quot; /&gt;
&lt;span asp-validation-for=&quot;InvHeader.InvDate&quot; class=&quot;text-danger&quot;&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;float:left;width:25%;&quot;&gt;
&lt;div class=&quot;form-group m-1&quot;&gt;
&lt;label asp-for=&quot;InvHeader.Cli&quot; class=&quot;control-label&quot; style=&quot;font-size:80%;&quot;&gt;Nr&lt;/label&gt;
&lt;input asp-for=&quot;InvHeader.InvNr&quot; class=&quot;form-control&quot; value=&quot;33&quot; /&gt;
&lt;span asp-validation-for=&quot;InvHeader.InvNr&quot; class=&quot;text-danger&quot;&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;/table&gt;
&lt;table id=&quot;table1&quot; border=&quot;0&quot;&gt;
&lt;tr style=&quot;font-size:80%;&quot;&gt;
&lt;th style=&quot;width:50%;&quot;&gt;Name&lt;/th&gt;
&lt;th style=&quot;width:5%;&quot;&gt;qty&lt;/th&gt;
&lt;th style=&quot;width:5%;&quot;&gt;price&lt;/th&gt;
&lt;/tr&gt;
@for (int i = 0; i &lt; Model.RowList.Count(); i++)
{
&lt;tr class=&quot;border-bottom&quot;&gt;
&lt;td&gt;
&lt;div class=&quot;form-group&quot;&gt;
&lt;input asp-for=&quot;@Model.RowList[@i].Name&quot; class=&quot;form-control&quot; name=&quot;RowList[@i].Name&quot;  /&gt;
&lt;span asp-validation-for=&quot;@Model.RowList[@i].Name&quot; class=&quot;text-danger&quot;&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;div class=&quot;form-group&quot;&gt;
&lt;input asp-for=&quot;@Model.RowList[@i].Qty&quot; class=&quot;form-control&quot; name=&quot;RowList[@i].Qty&quot; value=&quot;1&quot; /&gt;
&lt;span asp-validation-for=&quot;@Model.RowList[@i].Qty&quot; class=&quot;text-danger&quot;&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;div class=&quot;form-group&quot;&gt;
&lt;input asp-for=&quot;@Model.RowList[@i].Price&quot; class=&quot;form-control&quot; name=&quot;RowList[@i].Price&quot; value=&quot;33&quot; /&gt;
&lt;span asp-validation-for=&quot;@Model.RowList[@i].Price&quot; class=&quot;text-danger&quot;&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
}
&lt;/table&gt;
&lt;div class=&quot;form-group&quot;&gt;
&lt;input type=&quot;submit&quot; value=&quot;Create&quot; class=&quot;btn btn-primary&quot; /&gt;
&lt;a asp-page=&quot;Index&quot;&gt;Back to List&lt;/a&gt;
&lt;/div&gt;
&lt;/form&gt;

2. This is the backend code

 [BindProperty]
public InvHeader InvHeader { get; set; } = default!;
public IList&lt;InvRow&gt; RowList { get; set; }
public IActionResult OnGetAsync()
{
var rr = new List&lt;InvRow&gt;()
{
new InvRow() { Name = &quot;Apple&quot;, Qty = 5, Price = 100 },
new InvRow() { Name = &quot;Peach&quot;, Qty = 3, Price = 500 },
new InvRow() { Name = &quot;Ananas&quot;, Qty = 1, Price = 1100 },
};
RowList = rr;
return Page();
}
// To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task&lt;IActionResult&gt; OnPostAsync(IList&lt;InvRow&gt; RowList)
{
if (!ModelState.IsValid)
{
return Page();
}
_context.InvHeaders.Add(InvHeader);
await _context.InvRows.AddRangeAsync(RowList);
await _context.SaveChangesAsync();
return RedirectToPage(&quot;./Index&quot;);
}

huangapple
  • 本文由 发表于 2023年3月9日 22:56:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75686283.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定