Согласно этой странице документации Microsoft, следующий код должен отображать страницу, которая позволяет пользователю вводить данные формы, а нажатие кнопки отправки должно привести к выполнению метода Save
, в то время как Model
содержит привязку состояния из отправленной формы.
Когда я запускаю его, значения Person
всегда равны null
.
@page "/"
<PageTitle>Home</PageTitle>
<form @formname = "MyForm" method=post @onsubmit=Save>
<AntiforgeryToken />
Salutation <input name = "Salutation" [email protected] /><br/>
Personal name <input name = "PersonalName" [email protected] /><br />
Family name <input name = "FamilyName" [email protected] /><br />
<button type=submit>Save</button>
</form>
@code {
public class Person
{
public string? Salutation { get; set; }
public string? PersonalName { get; set; }
public string? FamilyName { get; set; }
}
[SupplyParameterFromForm(FormName = "MyForm")]
public required Person Model { get; set; }
protected override void OnInitialized()
{
base.OnInitialized();
Model ??= new();
}
private void Save()
{
if (Model?.Salutation is null)
throw new NullReferenceException("This should not happen");
}
}
Ваш код отличается от примера StarShip тремя способами. Все кажется критическим.
Вы ставите name
.
Вы используете необработанный input
, а в примерах — InputText
.
Вы не привязываете входные данные к модели двусторонней, а только односторонней привязке с помощью value=
.
Важным моментом является name
. Он должен соответствовать формату class.propertyname.
Итак, это работает:
@page "/"
<PageTitle>Home</PageTitle>
<form @formname = "Home" method = "post" @onsubmit = "this.Save">
<AntiforgeryToken />
Salutation: <input class = "mb-3" name = "Model.Salutation" value = "this.Model.Salutation" /><br />
Personal name: <input class = "mb-3" name = "Model.PersonalName" value = "this.Model.PersonalName" /><br />
Family name: <input class = "mb-3" name = "Model.FamilyName" value = "this.Model.FamilyName" /><br />
<button type=submit>Save</button>
</form>
@code {
[SupplyParameterFromForm]
public required Person Model { get; set; }
protected override void OnInitialized()
{
this.Model ??= new();
}
private void Save()
{
if (Model?.Salutation is null)
throw new NullReferenceException("This should not happen");
}
public class Person
{
public string? Salutation { get; set; }
public string? PersonalName { get; set; }
public string? FamilyName { get; set; }
}
}
InputText
автоматически добавляет поле имени.
Ответ заключался в том, что атрибуту name
на каждом входе также требуется имя свойства, к которому оно привязано. Поэтому вместо Salutation
должно быть Model.Salutation
.
Интересно, я не пробовал. Добавление имени модели.имя_свойства в качестве имени решило другие проблемы, которые я обнаружил. Нет необходимости в привязке.
Компонент <InputText> добавляет атрибут name
. Вы можете увидеть это в сгенерированном HTML. Если вы хотите включить эту дополнительную информацию в свой ответ, я с радостью ее приму.
Все объяснено. Я обновил ответ, чтобы отразить новые знания.
Фантастика, спасибо. Ответ принят!
Здесь вам понадобится правильное имя HTML-поля: github.com/dotnet/aspnetcore/issues/…