ASP.NET Razor Передача полного объекта в форме

У меня очень простая проблема, но кажется, что я не могу найти решение.

У меня есть объект, который инициализируется в моем методе OnGet. Я хочу, чтобы клиент обновил информацию, а затем обновил ее обратно в БД. (Некоторая информация об объекте хранится только в БД, но не видна и не редактируется пользователем)

Теперь я пытаюсь передать полный объект в своей форме в сочетании с входными данными от клиента. Если я попытаюсь получить доступ к объекту, все атрибуты будут нулевыми. Вместо этого, если я пытаюсь передать только один атрибут в виде строки в форме, он работает нормально.

Это мой код:

public class UpdateLicenseModel : PageModel
{
    private readonly license_backupContext _db;
    public UpdateLicenseModel(license_backupContext db)
    {
        _db = db;
    }
    public IList<License> Licenses { get; set; }

    [BindProperty]
    public License SelectedLicense { get; set; }


    [Auhtorize]
    public void OnGet()
    {
        Licenses = _db.License.ToList();
        SelectedLicense = Licenses.SingleOrDefault(s => s.Licenseid.ToString().Equals(LicenseString));
    }

    public IActionResult OnPost()
    {
        var license = SelectedLicense;
        if (!ModelState.IsValid)
        {
            return Page();
        }
        _db.License.Update(license);
        _db.SaveChanges();

        return RedirectToPage("./Licenses");
    }
}

В приведенном выше коде член лицензии в OnPost имеет значения только в полях, где пользователь что-то редактировал, все остальные поля пусты (не должны быть нулевыми)

Это моя форма (упрощенная):

<form method="post">
<div class="row">
    <div class="col-6 form-group">
        <label for="ID"><b>ID</b></label>
        <input class="form-control input-sm" id="ID" value="@Model.SelectedLicense.ID" asp-for="SelectedLicense.ID" />
    </div>
    <div class="col-6 form-group">
        <label for="Name"><b>Name</b></label>
        <input class="form-control input-sm" id="Name" value="@Model.SelectedLicense.Name" asp-for="SelectedLicense.Name" />
    </div>
</div>
<div class="row">
    <div class="col">
        <input type="submit" class="btn btn-success" value="Speichern" />
    </div>
</div>
<input type="hidden" asp-for="SelectedLicense" />
</form>

person Elias Johannes    schedule 03.10.2018    source источник


Ответы (1)


Вы не можете публиковать объекты .NET в HTML-формах так, как пытались. Вы можете только опубликовать их значения членов и позволить ModelBinding построить объект для вас на сервере.

Обычно вы используете скрытое поле для хранения значения ключа выбранного объекта, а затем используете это значение, чтобы определить, какая строка данных нуждается в обновлении в базе данных.

Или вы могли бы сериализовать SelectedLicense в JSON, а затем закодировать его с помощью Base64 или аналогичного и сохранить в скрытом поле. Затем вы можете декодировать и десериализовать его на сервере. Однако опытные пользователи будут иметь доступ к значению в браузере и смогут сами его декодировать.

person Mike Brind    schedule 03.10.2018
comment
Спасибо, это многое объясняет. Мне любопытно, какой будет лучшая практика. Должен ли я передать идентификатор объекта, а затем в моем OnPost снова загрузить список объектов и найти его в зависимости от идентификатора? - person Elias Johannes; 03.10.2018
comment
Вы можете либо загрузить его снова, либо просто создать обновление на основе отправленных значений. Если вы используете Entity Framework Core, вы должны использовать значение первичного ключа для создания объекта-заглушки, прикрепить его и установить переданные значения свойств как измененные: learnentityframeworkcore.com/dbcontext/modifying-data - person Mike Brind; 03.10.2018