【问题标题】:InvalidOperationException: Templates can be used only with field access, property access, single-dimension array index custom indexer expressionsInvalidOperationException:模板只能与字段访问、属性访问、单维数组索引自定义索引器表达式一起使用
【发布时间】:2021-05-14 17:09:40
【问题描述】:

为什么我收到输入表单错误?

@foreach (var user in Model.UsersWithItemsOption2)
{
<div>
    <div>@user.Items</div>

    @string.Join(", ", user.Items.Select(a => a.ItemName).ToList());

    <div>@user.Items.Select(a => a.ItemName)</div>

    <form method="post">
        //error 
        <input asp-for="@user.Items.Select(a => a.ItemName)" />
        //error 
        <button type="submit">Save</button>
    </form>
</div>
}

这是它的 C# 文件。

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ArrayCheckNetCore.Areas.Identity.Data;
using ArrayCheckNetCore.Data;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System.Linq;

namespace ArrayCheckNetCore.Areas.Identity.Pages.Account.Manage
{
    public class PersonalDataModel : PageModel
    {
        /// Inject DbContext
        readonly CheckArrayContext Context;

        /// Inject UserManager
        readonly UserManager<ApplicationUser> UserManager;


        public IEnumerable<ApplicationUser> UsersWithItemsOption2 { get; set; } = new 
List<ApplicationUser>();
        public IEnumerable<ApplicationUser> UsersWithItemsOption1 { get; set; } = new 
List<ApplicationUser>();
        public string Name { get; set; }

        public PersonalDataModel(
            CheckArrayContext Context,
            UserManager<ApplicationUser> UserManager)
        {
            this.Context = Context;
            this.UserManager = UserManager;
        }

        public async Task<IActionResult> OnGetAsync()
        {
            UsersWithItemsOption2 = await UserManager
                .Users
                .Include(a => a.Items)
                .ToListAsync();

            return Page();
        }

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

            await Context.SaveChangesAsync();

            return RedirectToPage("");
        }
    }
}

我得到一个错误

InvalidOperationException:模板只能用于字段访问、属性访问、一维数组索引或单参数自定义索引器表达式

我认为问题在于,它无法在表单提交上设置属性,或者asp-for='@user.Items.Select(a =&gt; a.ItemName)' 可能未在文件的上下文中定义。

如果有人知道如何解决此错误,谢谢。

【问题讨论】:

  • 您想为user.Items 中的每个项目创建一个输入?
  • 您好,我的回答有用吗?

标签: c# asp.net-mvc asp.net-core asp.net-core-mvc


【解决方案1】:

首先,asp-for不能绑定标签。可以参考link,asp-for有使用taghelper的示例。

如果你想一次性发布一个用户的物品,这里有一个demo(.net核心绑定数据name属性):

型号:

public class ApplicationUser
    {
        public List<Item> Items { get; set; }
    }
    public class Item
    {
        public string ItemName { get; set; }
    }

PersonData.cshtml:

@{ var usercount = 0;}

    @foreach (var user in Model.UsersWithItemsOption2)
    {
<div>
    <form method="post">
        @{ var itemscount = 0;}
        @foreach (var item in user.Items)
        {
            <input value="@item.ItemName" name="Items[@itemscount].ItemName" />
            itemscount++;
        }
        <button type="submit">Save</button>
    </form>

</div>
        usercount++;
    }

PersonData.cshtml.cs:

public class PersonalDataModel : PageModel
    {

        [BindProperty]
        public IEnumerable<ApplicationUser> UsersWithItemsOption2 { get; set; } = new
List<ApplicationUser>();
        public IEnumerable<ApplicationUser> UsersWithItemsOption1 { get; set; } = new
List<ApplicationUser>();
        public string Name { get; set; }

        public async Task<IActionResult> OnGetAsync()
        {
            UsersWithItemsOption2 = new List<ApplicationUser> { 
                new ApplicationUser { Items=new List<Item> { new Item {  ItemName="item01"}, new Item { ItemName = "item02" } } } ,
                new ApplicationUser { Items=new List<Item> { new Item {  ItemName="item11"}, new Item { ItemName = "item12" } } } ,
                new ApplicationUser { Items=new List<Item> { new Item {  ItemName="item21"}, new Item { ItemName = "item22" } } } ,

            };
            
                return Page();
        }

        public async Task<IActionResult> OnPostAsync(ApplicationUser user)
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }


            return RedirectToPage("");
        }
    }

结果: 如果你想发布所有用户的项目。这里有一个演示(我用UsersWithItemsOption2绑定表单数据):

PersonData.cshtml:

@{ var usercount = 0;}
<form method="post">
    @foreach (var user in Model.UsersWithItemsOption2)
    {
        <div>

            @{ var itemscount = 0;}
            @foreach (var item in user.Items)
            {
                <input value="@item.ItemName" name="UsersWithItemsOption2[@usercount].Items[@itemscount].ItemName" />
                itemscount++;
            }


        </div>
        usercount++;
    }
    <button type="submit">Save</button>
</form>

PersonData.cshtml.cs:

public class PersonalDataModel : PageModel
    {

        [BindProperty]
        public IEnumerable<ApplicationUser> UsersWithItemsOption2 { get; set; } = new
List<ApplicationUser>();
        public IEnumerable<ApplicationUser> UsersWithItemsOption1 { get; set; } = new
List<ApplicationUser>();
        public string Name { get; set; }

        public async Task<IActionResult> OnGetAsync()
        {
            UsersWithItemsOption2 = new List<ApplicationUser> { 
                new ApplicationUser { Items=new List<Item> { new Item {  ItemName="item01"}, new Item { ItemName = "item02" } } } ,
                new ApplicationUser { Items=new List<Item> { new Item {  ItemName="item11"}, new Item { ItemName = "item12" } } } ,
                new ApplicationUser { Items=new List<Item> { new Item {  ItemName="item21"}, new Item { ItemName = "item22" } } } ,

            };
            
                return Page();
        }

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


            return RedirectToPage("");
        }
    }

结果:

【讨论】:

  • 如何更新数据库中的表单值?
  • 你可以尝试使用efcore。这里是efcore的教程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-03
  • 1970-01-01
  • 2012-06-09
  • 1970-01-01
相关资源
最近更新 更多