简体   繁体   中英

Blazor binding a List<string> in an EditForm

I have a similar problem to this question in that I cannot get a Blazor EditForm to bind to a simple List.

Am I missing something in order to bind a List to an EditForm?

Person.cs

public class Person {
  public List<string>? Names { get; set; }
}

EditForm1.razor produces a compile-time error: Cannot assign to 'item' because it is a 'foreach iteration variable' . I get that - the iterator is read-only so I can understand that.

<EditForm Model="@person">
  @if (person is not null) {
    @if (person.Names is not null) {
      @foreach (var item in person.Names) {
        <InputText @bind-Value="@item" />
      }
    }
  }
</EditForm>

So, as per the referenced Microsoft documentation I refactored it.

EditForm2.razor compiles and runs... until person.Names actually has a value. It then throws ArgumentException: The provided expression contains a InstanceMethodCallExpression1 which is not supported. FieldIdentifier only supports simple member accessors (fields, properties) of an object. Microsoft.AspNetCore.Components.Forms.FieldIdentifier.ParseAccessor<T>(Expression<Func<T>> accessor, out object model, out string fieldName) ArgumentException: The provided expression contains a InstanceMethodCallExpression1 which is not supported. FieldIdentifier only supports simple member accessors (fields, properties) of an object. Microsoft.AspNetCore.Components.Forms.FieldIdentifier.ParseAccessor<T>(Expression<Func<T>> accessor, out object model, out string fieldName)

<EditForm Model="@person">
  @if (person is not null) {
    @if (person.Names is not null) {
      @for (int x = 0; x < person.Names.Count; x++) {
        <InputText @bind-Value="@person.Names[x]" />
      }
    }
  }
</EditForm>

EditForm3.razor is my last attempt. This compiles and renders, but as soon as I try and do anything with the edit box the app crashes with Unhandled exception rendering component: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index') Unhandled exception rendering component: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index') Unhandled exception rendering component: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index') . I'm 99% sure this approach is wrong but I am now clutching at straws.

<EditForm Model="@person">
  @if (person is not null) {
    @if (person.Names is not null) {
      @for (int x = 0; x < person.Names.Count; x++) {
        <input @bind="@person.Names[x]" />
      }
    }
  }
</EditForm>

The answer is in the accepted answer you linked to...

You are looking to create a two-way data binding of a collection.

<EditForm Model="@person">
    @foreach (var PName in person.names) 
    {
        <InputText @bind-Value="@PName.Name" />
    }
 </EditForm>

@code
{
private Person person = new Person {ID = "1", names = new List<PersonName>() 
                { new PersonName {Name = "Marry" }, 
                  new PersonName {Name = "Marria" } 
                };

public class Person
{
   public string ID {get;set;}
   public List<PersonName> names { get; set; }
}

public class PersonName 
{
    public string Name { get; set; }
}

} 

Note that in order to bind the Name property, you must define it in a class of its own, and in the Person model you define a list of that class ( PersonName ). This is the only way to bind to a collection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM