更新相关实体 [英] Updating related entities

查看:94
本文介绍了更新相关实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

AppUser 身份模型:

公共虚拟ICollection< UserPhones>用户电话{放;}

使用Razor Pages,我称为局部视图,如下所示:

Using Razor Pages, I call a partial view, like so:

@await Html.PartialAsync("_ NameAndID",Model.AppUser)

PageModel:

PageModel:

[BindProperty]
public AppUser AppUser { get; set; }

 public IActionResult OnGet()
    {
        AppUser = _userManager.Users
                //.Include(x => x.UserAddresses) //OMITTED BC USING LAZY LOADING
                .SingleOrDefaultAsync(x => x.UserName == 
                     _httpContext.HttpContext.User.Identity.Name).Result;

        return Page();
    }

_NameAndID.cshtml 中,我明确引用了 UserPhones 实体中的特定电话.使用:

Within _NameAndID.cshtml, I explicitly reference a particular telephone from the UserPhones entity. With:

<input type="hidden" asp-for="UserPhones
   .SingleOrDefault(z => z.Type == EnumPhoneType.Mobile).UserPhoneId" />

//other properties removed for brevity           

<div class="rvt-grid__item">
    <label asp-for="UserPhones.SingleOrDefault(z => z.Type == EnumPhoneType.Mobile).PhoneNumber">Mobile Phone</label>
    <input asp-for="UserPhones.SingleOrDefault(z => z.Type == EnumPhoneType.Mobile).PhoneNumber" autocomplete="tel" />
    <span asp-validation-for="UserPhones.SingleOrDefault(z => z.Type == EnumPhoneType.Mobile).PhoneNumber"></span>
</div>

在运行时,显式手机号码已正确加载.但是,当发布到公共异步任务< IActionResult>时,OnPostAsync()相关的 AppUser.UserPhones null .(问题)

At runtime, the explicit mobile phone number is loaded properly. However when posting to public async Task<IActionResult> OnPostAsync() the related AppUser.UserPhones is null. (The problem)

你能帮忙吗?

预先感谢您!!!!

推荐答案

原因

在这种情况下, asp-for 不能很好地工作.

考虑您在 _NameAndID.cshtml 中的代码:

<input asp-for="UserPhones.SingleOrDefault(z => z.Type == EnumPhoneType.Mobile).PhoneNumber" autocomplete="tel" />

请注意此处的LINQ扩展方法 .SingleOrDefault(...).此处的 asp-for 不知道如何获取 UserPhones.SingleOrDefault(z => z.Type == EnumPhoneType.Mobile).PhoneNumber 的名称,因此只需将其呈现为 PhoneNumber .结果,呈现的html将是:

Note the LINQ extension method .SingleOrDefault(...) here. The asp-for here does not know how to get the name for UserPhones.SingleOrDefault(z => z.Type == EnumPhoneType.Mobile).PhoneNumber, so it just render it as PhoneNumber. As a result, the rendered html will be :

<input autocomplete="tel" type="text" id="PhoneNumber" name="PhoneNumber" value="">

假设某人输入了 911 的值,当发布到服务器时,有效负载将为:

Let's say someone inputs an value of 911, when posted to server, the payload will be :

PhoneNumber=911

因为您在服务器端的页面模型是:

As your page model on server side is :

    [BindProperty]
    public AppUser AppUser{get;set;}

    public IActionResult OnGet()
    {
        // ...
    }

    public IActionResult OnPostAsync() 
    {
        return Page();
    }

请注意 AppUser.UserPhones 属性是一个集合.换句话说, AppUser 需要一个有效载荷,例如:

Note the AppUser.UserPhones property is a collection. in other words, AppUser expects a payload like :

UserPhones[0].UserPhoneId=1&UserPhones[0].PhoneNumber=911&UserPhones[1].UserPhoneId=2&UserPhones[1].PhoneNumber=119

但是,您发送到服务器的是:

However, what you send to the server is :

PhoneNumber=911

因此, App.UserPhones 始终为null,而 AppUser.PhoneNumber 属性将为 911 .

So the App.UserPhones will always be null and the AppUser.PhoneNumber property will be 911.

首先,为了自动绑定 UserPhones ,我将 App.UserPhones 的类型更改为 IList< UserPhones> ,我们可以使用索引语法

Firstly, in order to bind the UserPhones automatically, I change the type of App.UserPhones to IList<UserPhones> , so that we can use a index syntax

public class AppUser : IdentityUser{

    // public virtual ICollection<UserPhones> UserPhones { get; set; }
    public virtual IList<UserPhones> UserPhones { get; set; }

}

第二,不要在 asp-for 中使用复杂的查询,而应使用简单的索引语法.例如,如果您想发布一些 UserPhones 或发布所有 UserPhones ,则可以为每个字段添加一个索引:

Secondly, don't use complex query in asp-for, use simple index syntax instead. For example, if you would like to post some UserPhones or post all UserPhones, you can add an index for each field :

@for(var i=0;i <Model.UserPhones.Count(); i++) {

    <div class="rvt-grid__item">
        <label asp-for="@Model.UserPhones[i].UserPhoneId"></label>
        <input asp-for="@Model.UserPhones[i].UserPhoneId"/>
        <label asp-for="@Model.UserPhones[i].PhoneNumber"></label>
        <input asp-for="@Model.UserPhones[i].PhoneNumber"/>
        <span asp-validation-for="@Model.UserPhones[i].PhoneNumber"></span>
    </div>
}

通过这种方式,当有人提交表单时,将正确设置 AppUser.UserPhones .这是演示的屏幕截图:

In this way, when someone submits the form, AppUser.UserPhones will be the correctly set. Here's a screenshot of demo :

这篇关于更新相关实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆