Почему значения не сохраняются в Postback? - PullRequest
0 голосов
/ 23 апреля 2019

На моей домашней странице есть список параметров продукта, каждый из которых предоставляет пользователю свой уровень учетной записи при регистрации. Каждая опция представляет собой кнопку «Зарегистрироваться», которая переводит пользователя на страницу /Identity/Account/Register, чтобы зарегистрироваться.

Мне нужно сообщить странице регистрации, какую опцию выбрал пользователь.

  1. Я не могу использовать сеансы, потому что это, очевидно, забрали
  2. Я не могу использовать куки-файлы, потому что их явно забрали
  3. Значения ViewData не сохраняются при отправке формы
  4. Значения строки запроса не сохраняются при отправке формы
  5. Значения глобальной переменной не сохраняются при отправке формы
  6. Я не могу установить свойства модели представления при начальной загрузке страницы (NullReferenceException)

Когда страница регистрации загружается, значение есть, но когда я отправляю форму, она исчезает.

Я в растерянности. По какому механизму я имею в виду передачу этой необходимой информации?

По большей части мой код в основном просто стандартный материал:

[AllowAnonymous]
public class RegisterModel : PageModel
{
    private readonly SignInManager<ApplicationUser> _signInManager;
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly ILogger<RegisterModel> _logger;
    private readonly IEmailSender _emailSender;

    public RegisterModel(
        UserManager<ApplicationUser> userManager,
        SignInManager<ApplicationUser> signInManager,
        ILogger<RegisterModel> logger,
        IEmailSender emailSender)
    {
        _userManager = userManager;
        _signInManager = signInManager ?? throw new ArgumentNullException(nameof(signInManager));
        _logger = logger;
        _emailSender = emailSender;
    }

    [BindProperty]
    public InputModel Input { get; set; }
    [BindProperty]
    public int AccountLevel { get; set; }
    public string ReturnUrl { get; set; }

    public void OnGet(string returnUrl = null, int acclevel = 1)
    {
        AccountLevel = acclevel;
        ReturnUrl = returnUrl;
    }

    public async Task<IActionResult> OnPostAsync(string returnUrl = null, int acclevel = 0)
    {
        returnUrl = returnUrl ?? Url.Content("~/");

        if (ModelState.IsValid)
        {
            if (acclevel == 0) throw new ArgumentException(nameof(acclevel));

            Input.LicenseCount = acclevel * 10;

            var user = new ApplicationUser { UserName = Input.Email, Email = Input.Email, Name = Input.FirstName, Surname = Input.Surname, PhoneNumber = Input.PhoneNumber, SaIdNumber = Input.IdNumber, LicensesCount = Input.LicenseCount };

            var result = await _userManager.CreateAsync(user, Input.Password);
            await _userManager.AddToRoleAsync(user, nameof(SystemRoles.AppUser));
            if (result.Succeeded)
            {
                _logger.LogInformation("User created a new account with password.");

                var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                var callbackUrl = Url.Page(
                    "/Account/ConfirmEmail",
                    pageHandler: null,
                    values: new { userId = user.Id, code = code },
                    protocol: Request.Scheme);

                await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                    $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

                //await _signInManager.SignInAsync(user, isPersistent: false);
                return LocalRedirect(returnUrl);
            }
            foreach (var error in result.Errors)
            {
                ModelState.AddModelError(string.Empty, error.Description);
            }
        }

        // If we got this far, something failed, redisplay form
        return Page();
    }
}

Вот страница (здесь по какой-то причине используются страницы с PageModel, а не представления и контроллеры - таким образом она создавалась при добавлении идентификатора).

@page
@model RegisterModel
@{
    ViewData["Title"] = "Register";
}

<h1>@ViewData["Title"]</h1>

<div class="row">
    <div class="col-md-4">
        <form asp-route-returnUrl="@Model.ReturnUrl" method="post">
            <h4>Create a new account.</h4>
            <hr />
            <div asp-validation-summary="All" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Input.FirstName"></label>
                <input asp-for="Input.FirstName" class="form-control" />
                <span asp-validation-for="Input.FirstName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Input.Surname"></label>
                <input asp-for="Input.Surname" class="form-control" />
                <span asp-validation-for="Input.Surname" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Input.PhoneNumber"></label>
                <input asp-for="Input.PhoneNumber" class="form-control" />
                <span asp-validation-for="Input.PhoneNumber" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Input.IdNumber"></label>
                <input asp-for="Input.IdNumber" class="form-control" />
                <span asp-validation-for="Input.IdNumber" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Input.Email"></label>
                <input asp-for="Input.Email" class="form-control" />
                <span asp-validation-for="Input.Email" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Input.Password"></label>
                <input asp-for="Input.Password" class="form-control" />
                <span asp-validation-for="Input.Password" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Input.ConfirmPassword"></label>
                <input asp-for="Input.ConfirmPassword" class="form-control" />
                <span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
            </div>
            <button type="submit" class="btn btn-primary">Register</button>
        </form>
    </div>
</div>

@section Scripts {
    <partial name="_ValidationScriptsPartial" />
}

Ответы [ 2 ]

1 голос
/ 23 апреля 2019

Примечание: я не работаю с Razor Pages, поэтому кто-то со знанием этой технологии может иметь лучший ответ.

Вы можете использовать скрытое поле в форме, чтобы сохранитьзначение на POST-back:

<form asp-route-returnUrl="@Model.ReturnUrl" method="post">
    @Html.HiddenFor(model => model.AccountLevel)
    @*OR, TagHelper way*@
    <input asp-for="AccountLevel" type="hidden"/>
    <h4>Create a new account.</h4>
    ....
</form>

Это также довольно легко сделать с сеансами после их включения :

public void OnGet(string returnUrl = null, int acclevel = 1)
{
    HttpContext.Session.SetInt32("AccountLevel", acclevel);
    ReturnUrl = returnUrl;
}

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    int accountLevel = HttpContext.Session.GetInt32("AccountLevel");
    ...
}
0 голосов
/ 23 апреля 2019

Единственные данные, которые существуют после запроса, это то, что отправлено вместе с этим запросом.Даже в случае сессий ключевой идентификатор сеанса должен быть передан клиентом на сервер в запросе для восстановления этого сеанса.

Любые данные, которые вы извлекли из базы данных, должны быть опубликованы или опрошеныснова.Кроме того, не следует публиковать данные, которые нельзя явно изменить пользователю.В результате большая часть данных должна быть запрошена снова.

Что касается выбранной пользователем опции, то она, конечно, должна быть опубликована.Тем не менее, фактические детали выбранного плана и других вариантов плана должны быть получены путем повторного запроса этой базы данных.Это будет необходимо, например, если вам необходимо повторно отобразить форму после публикации из-за ошибки проверки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...