В чем разница между Page () и Rediirect () для себя на страницах ASP.NET Core Razor? - PullRequest
0 голосов
/ 29 сентября 2018

У меня очень простая страница с двумя формами.Когда я отправляю одну форму, она сбрасывает другую.Существует какая-то скрытая оптимизация, потому что когда я обновляю страницу, она показывает правильный результат.

Вот эта страница:

<div asp-validation-summary="All"></div>
<div class="col-md-3">
   <form method="POST">
        <fieldset>
            <div>Host Name: <input asp-for="ClientConfig.HostName" /></div>
            <div>Responses in HTML? <input type="checkbox" asp-for="ClientConfig.Html" /></div>
            <input type="submit" asp-page-handler="ClientConfiguration" />
        </fieldset>
   </form>
   <p>Base URL = @Model.ClientConfig.Summary</p>
</div>
<form method="POST">
    <fieldset>
        <div>Name: <input asp-for="Customer.Name" /></div>
        <div>New? <input type="checkbox" asp-for="Customer.New" /></div>
        <input type="submit" asp-page-handler="Customer" />
    </fieldset>
</form>
<ul>
    <li>Customer = @Model.Customer.Summary</li>
</ul>

Вот модель ...

public class ClientConfig
{
    public static ClientConfig Instance { get; set; } = new ClientConfig();
    [Required, StringLength(100)] public string HostName { get; set; } = "LocalHost";
    public bool Html { get; set; }
    public string Summary => HostName + (Html ? " (Html)" : "");
}
public class Customer
{
    public static Customer Instance { get; set; } = new Customer();
    [Required, StringLength(100)] public string Name { get; set; } = "Default";
    public bool New { get; set; }
    public string Summary => Name + (New ? " (New)" : "");
}
public class IndexModel : PageModel
{
    public IndexModel()
    {
        ClientConfig = ClientConfig.Instance;
        Customer = Customer.Instance;

    }
    [BindProperty] public ClientConfig ClientConfig { get; set; }
    [BindProperty] public Customer Customer { get; set; }
    public async Task<IActionResult> OnPostCustomerAsync()
    {
        Customer.Instance = Customer;
        return Page();
    }
    public async Task<IActionResult> OnPostClientConfigurationAsync()
    {
       ClientConfig.Instance = ClientConfig;
        return Page();
    }
}

Так что же такое «return Page ();»делать?Согласно документации это просто рендеринг текущей страницы.Не правда.Чтобы убедиться в этом, просто обновите страницу.Он будет другим, точным с заполнением обеих форм. Также, если вы замените «return Page ()» на «return Redirect (« / Index »);»результат также будет точным.Итак, еще раз, что делает "return Page ()"?Существует некоторая недокументированная оптимизация, которая сбрасывает все формы, кроме недавно отправленной.

Ответы [ 3 ]

0 голосов
/ 01 октября 2018

У вас есть несколько отдельных форм на вашей странице с отдельными значениями формы: в одной форме вы отправляете объект конфигурации клиента, в другой вы отправляете объект клиента.

Таким образом, когда вы фактически отправляетеформа, только данные этой формы представляются.Например, если вы отправляете форму клиента, данные конфигурации клиента не передаются в запросе POST (и наоборот).

Таким образом, когда вы отображаете страницу, возвращая Page()отображаются только те данные, которые в данный момент находятся в модели страницы.Если вы отправляете форму клиента, тогда доступны только данные клиента (то же самое для формы конфигурации клиента).

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

Теперь, если вы обновите страницу в браузере, то ваш браузер обычно достаточно умен не для немедленной очистки значений формы.Если вы выполняете полное обновление, используя Ctrl + F5 , тогда браузер также должен сбросить значения.

Также возможно, что ваш браузер выполняет автоматическое заполнение форм здесь.Обычно это относится только к запросам GET.Так что это может быть причиной того, что вы получаете этот результат, когда вы возвращаете Redirect(), потому что это завершает форму POST с запросом GET.

0 голосов
/ 07 апреля 2019

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

Мое первоначальное предположение было неверным.Конструктор модели страницы не обойден.Модель страницы строится правильно из статических значений.Однако после построения все связанные объекты на странице сбрасываются.Так что это не «недокументированная оптимизация» ... это недокументированное ухудшение.

Исправление для этого состоит в том, чтобы сбросить модель страницы из статических значений перед возвратом Page ().

    public async Task<IActionResult> OnPostCustomerAsync()
    {
        Customer.Instance = Customer;
        ClientConfig = ClientConfig.Instance;
        return Page();
    }
    public async Task<IActionResult> OnPostClientConfigurationAsync()
    {
       ClientConfig.Instance = ClientConfig;
       Customer = Customer.Instance;
        return Page();
    }

Это, очевидно, огромный шаг, но элегантного решения не существует.Кто-нибудь?

0 голосов
/ 30 сентября 2018

Когда я отправляю одну форму, она сбрасывает другую.

Это ожидаемое поведение при кодировании вашей страницы.Когда форма отправляет POST серверу, сервер делает три вещи:

  1. создает новый объект IndexModel, используя его конструктор,
  2. привязывает свойства объекта к значениям формы POSTed,и
  3. привязывает объект к его виду.

В вашем коде шаг (1) сбрасывает свойства до значений по умолчанию.Шаг (2) перезаписывает эти значения по умолчанию значениями формы POST.Поскольку вы отправляете только одну форму, значения другой формы сохраняют свои значения по умолчанию.Вот почему отправка одного сбрасывает другого.

Так что же такое «return Page ();»делать?Согласно документации это просто рендеринг текущей страницы.Не правда.Чтобы убедиться в этом, просто обновите страницу.Он будет другим, точным с заполнением обеих форм. Также, если вы замените «return Page ()» на «return Redirect (« / Index »);»результат также будет точным.

Когда вы отправляете форму, return Page() отображает страницу в контексте POST.С другой стороны, когда вы обновляете или перенаправляете, контекст становится GET.Разница, которую вы видите, возникает потому, что контекст отличается: ответ на POST отличается от ответа на GET.

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