ASP.Net Core:如何更新(更改/添加/删除)嵌套项对象(一对多关系)?

2024-01-06

我有一个带有“MSCustomers”和“MSLocations”的.Net 5.x 项目。 MSLocations 与 MSCustomers 之间存在多对一的关系。

我的“编辑”页面正确显示“MSCustomer”记录和相应的“MSLocations”字段。

PROBLEM:

“编辑”应该允许我修改或“删除”任何 MSLocation。但是当我保存记录时,所有 MSLocations 都没有改变。

MSCustomer.cs:

public class MSCustomer
{
    public int ID { get; set; }
    public string CustomerName { get; set; }
    public string EngagementType { get; set; }
    public string MSProjectNumber { get; set; }
    // EF Navigation
    public virtual ICollection<MSLocation> MSLocations { get; set; }
 }

MSLocation.cs

public class MSLocation
{
    public int ID { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
    public int MSCustomerId { get; set; }  // FK
    // EF Navigation
    public MSCustomer MSCustomer { get; set; }
}

编辑.cshtml.cs:

public class EditModel : PageModel
{
    [BindProperty]
    public MSCustomer MSCustomer { get; set; }
    ...
    public IActionResult OnGet(int? id)
    {          
        if (id == null)
            return NotFound();

        MSCustomer = ctx.MSCustomer
            .Include(location => location.MSLocations)
            .FirstOrDefault(f => f.ID == id);

        return Page();  // This all works...
    }

    public async Task<IActionResult> OnPostAsync(string? submitButton)
    {
        ctx.Attach(MSCustomer).State = EntityState.Modified;
        await ctx.SaveChangesAsync();

        return RedirectToPage("Index"); // Saves MSCustomer updates, but not MSLocations...

编辑.cshtml.cs

@page
@model HelloNestedFields.Pages.MSFRD.EditModel
@using HelloNestedFields.Models
...
<form method="POST">
    <input type="hidden" asp-for="MSCustomer.ID" />
    ...
    <table>
        <thead>
            <tr>
                <th style="min-width:140px">Address</th>
                <th style="min-width:140px">City</th>
                <th style="min-width:140px">State</th>
                <th style="min-width:140px">Zip</th>
            </tr>
        </thead>
        <tbody>
            @foreach (MSLocation loc in @Model.MSCustomer.MSLocations)
            {
                <tr id="[email protected] /cdn-cgi/l/email-protection">
                    <td><input asp-for="@loc.Address" /></td>
                    <td><input asp-for="@loc.City" /></td>
                    <td><input asp-for="@loc.State" /></td>
                    <td><input asp-for="@loc.Zip" /></td>
                    <td><button onclick="removeField(@loc.ID);">Remove</button></td>
                </tr>
            }
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
                <td><button id="add_location_btn">Add Location</button></td>
            </tr>
        </tbody>
    </table>
    ...
@section Scripts {
<script type="text/javascript">
    function removeField(element_id) {
        try {
          let row_id = "row_" + element_id;
          console.log("removeField, element_id=" + element_id + ", row_id=" + row_id + "...");
          let tr = document.getElementById(row_id);
          console.log("tr:", tr);
          tr.parentNode.removeChild(tr);
        } catch (e) {
          console.error(e);
        }
        debugger;
    };
</script>

}

HelloNestedContext.cs

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

    public DbSet<HelloNestedFields.Models.MSCustomer> MSCustomers { get; set; }
    public DbSet<HelloNestedFields.Models.MSLocation> MSLocations { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MSCustomer>()
            .HasMany(d => d.MSLocations)
            .WithOne(c => c.MSCustomer)
            .HasForeignKey(d => d.MSCustomerId);
    }
}

问:我缺少什么?

问:我需要做什么才能MS客户.MS位置更新是否从浏览器传递回 OnPostAsync(),并正确保存?

我确定是POSSIBLE。但我无法在任何地方找到任何文档或示例代码来修改“记录对象”中的“嵌套项目对象”。

任何建议将非常受欢迎!


Update:

Razor 页面似乎不支持绑定到“复杂”对象(在记录中具有嵌套列表)。

因此,我尝试了下面 Okan Karadag 的出色建议 - 我将“MSLocations”拆分为自己的绑定,然后将其添加回“POST”处理程序中的“MSCustomer”。这让我CLOSER- 至少现在我可以更新嵌套字段。但我仍然无法在“编辑”页面中添加或删除 MSLocation。

新建Edit.cshtml.cs

[BindProperty]
public MSCustomer MSCustomer { get; set; }
[BindProperty]
public List<MSLocation> MSLocations { get; set; }
...

public IActionResult OnGet(int? id)
{          
    MSCustomer = ctx.MSCustomer
        .Include(location => location.MSLocations)
        .FirstOrDefault(f => f.ID == id);
    MSLocations = new List<MSLocation>(MSCustomer.MSLocations);
   ...

public async Task<IActionResult> OnPostAsync(string? submitButton)
{
    MSCustomer.MSLocations = new List<MSLocation>(MSLocations);  // Update record with new
    ctx.Update(MSCustomer);
    await ctx.SaveChangesAsync();
   ...

新建编辑.cshtml

<div class="row">
    ...
    <table>
        ...
        <tbody id="mslocations_tbody">
            @for (int i=0; i < Model.MSLocations.Count(); i++)
            {
                <tr id="[email protected] /cdn-cgi/l/email-protection[i].ID">      
                    <td><input asp-for="@Model.MSLocations[i].Address" /></td>
                    <td><input asp-for="@Model.MSLocations[i].City" /></td>
                    <td><input asp-for="@Model.MSLocations[i].State" /></td>
                    <td><input asp-for="@Model.MSLocations[i].Zip" /></td>
                    <td>
                        <input type="hidden" asp-for="@Model.MSLocations[i].ID" />
                        <input type="hidden" asp-for="@Model.MSLocations[i].MSCustomerId" />
                        <button onclick="removeLocation([email protected] /cdn-cgi/l/email-protection[i].ID);">Remove</button>
                    </td>
                </tr>
            }
        </tbody>
    </table>
    <button onclick="addLocation();">Add Location</button>
</div>

当前状态:

  • 我可以更新顶级“MSCustomer”数据字段。
  • 我可以更新现有的“MSlocation”字段。
  • I CANNOT添加新的或删除当前的 MSLocation 项目。
  • “拦截器”似乎是 Razor 绑定:将“更新的”MSLocations 列表从 Razor“编辑”页面传送回 C#“POST”操作处理程序。

我的下一步将尝试这个:

如何将来自不同实体的项目动态添加到 ASP.NET Core MVC 中的列表 https://stackoverflow.com/questions/63487500/how-to-dynamically-add-items-from-different-entities-to-lists-in-asp-net-core-mv

如果有效的话那就太好了。就会是均匀的BETTER如果有一个不涉及 Ajax 调用的更简单的替代方案..


发送数据时,应该是customer.Locations[0].City : "foo" customer.Locations[1].City : "bar",您应该发布为 Locations[index]。您可以在浏览器的网络选项卡中查看传递的数据。

解决方案 1(与for)

@for (var i = 0; i < Model.MSCustomer.Locations.Count(); i++)
{
    <tr id="[email protected] /cdn-cgi/l/email-protection">
        <td><input asp-for="@Model.MSCustomer.Locations[i].Address" /></td>
        <td><input asp-for="@Model.MSCustomer.Locations[i].City" /></td>
        <td><input asp-for="@Model.MSCustomer.Locations[i].State" /></td>
        <td><input asp-for="@Model.MSCustomer.Locations[i].Zip" /></td>
        <td><button onclick="removeField(@loc.ID);">Remove</button></td>
     </tr>
}

解决方案2(与foreach)

@foreach (MSLocation loc in @Model.MSCustomer.MSLocations)
{
    <tr id="[email protected] /cdn-cgi/l/email-protection">
        <td><input asp-for="@Model.MSCustomer.MSLocations[loc.Id].Address" /></td>
        <td><input asp-for="@Model.MSCustomer.MSLocations[loc.Id].City" /></td>
        <td><input asp-for="@Model.MSCustomer.MSLocations[loc.Id].State" /></td>
        <td><input asp-for="@Model.MSCustomer.MSLocations[loc.Id].Zip" /></td>
        <td><button onclick="removeField(@loc.ID);">Remove</button></td>
    </tr>
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ASP.Net Core:如何更新(更改/添加/删除)嵌套项对象(一对多关系)? 的相关文章

  • 使用 CMake 时如何导出 Emscripten 中的 C 函数

    In 本教程 https emscripten org docs porting connecting cpp and javascript Interacting with code html interacting with code
  • 在 CPP 类中将 C 函数声明为友元

    我需要在 C 函数中使用类的私有变量 我正在做这样的事情 class Helper private std string name public std getName return name friend extern C void in
  • 循环遍历 C 结构中的元素以提取单个元素的值和数据类型

    我有一个要求 我有一个 C 语言的大结构 由大约 30 多个不同数据类型的不同元素组成 typedef struct type1 element1 type2 element2 type3 element3 type2 element4 1
  • 当事件button.click发生时,如何获取按钮名称/标签?

    我以编程方式制作按钮并将它们添加到堆栈面板中 以便每次用户导航到页面时按钮都会发生变化 我正在尝试做这样的事情 当我单击创建的按钮时 它将获取按钮的标签并转到正确的页面 但是 我无法使用 RoutedEventHandler 访问按钮元素
  • 传递 constexpr 对象

    我决定给予新的C 14的定义constexpr旋转并充分利用它 我决定编写一个小的编译时字符串解析器 然而 我正在努力保持我的对象constexpr将其传递给函数时 考虑以下代码 include
  • 有些有助于理解“产量”

    在我不断追求少吸的过程中 我试图理解 产量 的说法 但我不断遇到同样的错误 someMethod 的主体不能是迭代器块 因为 System Collections Generic List 不是迭代器接口类型 这是我被卡住的代码 forea
  • 如何使用 ASP.NET Core 获取其他用户的声明

    我仍在学习 ASP NET Core 的身份 我正在进行基于声明的令牌授权 大多数示例都是关于 当前 登录用户的 就我而言 我的 RPC 服务正在接收身份数据库中某个用户的用户名和密码 我需要 验证是否存在具有此类凭据的用户 获取该用户的所
  • 获取没有显式特征的整数模板参数的有符号/无符号变体

    我希望定义一个模板类 其模板参数始终是整数类型 该类将包含两个成员 其中之一是类型T 另一个作为类型的无符号变体T 即如果T int then T Unsigned unsigned int 我的第一直觉是这样做 template
  • 在 C# 中检查 PowerShell 执行策略的最佳方法是什么?

    当你跑步时Get ExecutionPolicy在 PowerShell 中 它得到有效的执行政策 https learn microsoft com en us powershell module microsoft powershell
  • 在 VS 中运行时如何查看 C# 控制台程序的输出?

    我刚刚编写了一个名为 helloworld 的聪明程序 它是一个 C NET 4 5 控制台应用程序 在扭曲的嵌套逻辑迷宫深处 使用了 Console WriteLine 当我在命令行运行它时 它会运行并且我会看到输出 我可以执行其他命令并
  • 如何将AVFrame转换为glTexImage2D使用的纹理?

    如您所知 AVFrame 有 2 个属性 pFrame gt data pFrame gt linesize 当我从视频 sdcard test mp4 android平台 读取帧后 并将其转换为RGB AVFrame副 img conve
  • 无法通过docker连接到ASP.NET Core

    大家好 人们已经关注这个问题太久了 需要一些帮助 我制作了一个 ASP NET Core 网站 没有什么特别的 只是 VS 2017 v 1 1 附带的模板 我使用 dotnet core cli 发布网站并使用此 dockerfile 构
  • 在 .NET MAUI 中实现 TouchTracking

    我一直致力于将我们的应用程序从 Xamarin Forms 迁移到 NET MAUI 我们的应用程序几乎没有绘图功能 用户可以用手指进行绘图 我们用了TouchTrackingXamarin Forms 中的 nuget 包 但与 NET
  • 如果输入被重定向则执行操作

    我想知道如果我的输入被重定向 我应该如何在 C 程序中执行操作 例如 假设我有已编译的程序 prog 并且我将输入 input txt 重定向到它 我这样做 prog lt input txt 我如何在代码中检测到这一点 一般来说 您无法判
  • 模板外部链接?谁能解释一下吗?

    模板名称具有链接 3 5 非成员函数模板可以有内部链接 任何其他模板名称应具有外部链接 从具有内部链接的模板生成的实体与在其他翻译单元中生成的所有实体不同 我知道使用关键字的外部链接 extern C EX extern C templat
  • 在 C# 中为父窗体中的子窗体控件添加事件处理程序

    我有两种形式 一种是带有按钮和文本框的父表单 单击该按钮时 将打开一个对话框 该子窗体又包含一个文本框和一个按钮 现在我想要的是 每当子表单文本框中的文本更改时 父表单文本框中的文本会自动更改 为了获得这个 我所做的是 Form3 f3 n
  • 在 C 中使用枚举而不是 #defines 作为编译时常量是否合理?

    在 C 工作了一段时间后 我将回到 C 开发领域 我已经意识到 在不必要的时候应该避免使用宏 以便让编译器在编译时为您做更多的工作 因此 对于常量值 在 C 中我将使用静态 const 变量或 C 11 枚举类来实现良好的作用域 在 C 中
  • 比较:接口方法、虚方法、抽象方法

    它们各自的优点和缺点是什么 接口方法 虚拟方法 抽象方法 什么时候应该选择什么 做出这一决定时应牢记哪些要点 虚拟和抽象几乎是一样的 虚方法在基类中有一个实现 可以选择重写 而抽象方法则没有 并且must在子类中被覆盖 否则它们是相同的 在
  • 如何在 sql azure 上运行 aspnet_regsql? [复制]

    这个问题在这里已经有答案了 可能的重复 将 ASP NET 成员资格数据库迁移到 SQL Azure https stackoverflow com questions 10140774 migrating asp net membersh
  • 我可以使用 lambda 函数或 std::function 对象来代替函数指针吗?

    我有一个需要使用的库 它定义了以下内容 typedef void CallbackFunction const int i 并且有一个注册回调的函数 如下所示 void registerCallback CallbackFunction p

随机推荐