代码之家  ›  专栏  ›  技术社区  ›  AQuirky

在ASP.NET Core Razor页面中,Page()和redirect()对self的区别是什么?

  •  2
  • AQuirky  · 技术社区  · 8 年前

    这是一页:

    <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()”又在做什么呢?有一种未记录的优化可以重置除最近提交的表单之外的所有表单。

    2 回复  |  直到 8 年前
        1
  •  1
  •   poke    8 年前

    页面上有多个具有单独表单值的单独表单:在一个表单中提交客户机配置对象,在另一个表单中提交客户机对象。

    所以当你实际提交一个表单时,只有该表单的数据被提交。例如,如果要提交客户表单,则不会在POST请求中传输客户机配置数据(反之亦然)。

    因此,当您通过返回 Page()

    这种情况发生的原因很简单,因为页面上只有部分数据,需要更多的数据来填写所有表单。如果要防止这种情况发生,则必须将数据合并到单个模型和表单中。

    现在,如果您在浏览器中刷新页面,那么您的浏览器通常足够智能 不 立即清除窗体值。如果您使用 ,则浏览器也应重置这些值。

    Redirect() 因为这就完成了带有GET请求的表单POST。

        2
  •  0
  •   Shaun Luttin    8 年前

    这是您对页面编码方式的预期行为。当表单发送到服务器时,服务器会执行三项操作:

    1. IndexModel 对象使用其构造函数,
    2. 将对象的属性绑定到已发布的表单值,以及
    3. 将对象绑定到其视图。

    那么“return Page();”在做什么呢?根据文档,它只是呈现当前页面。不是真的。要验证这一点,只需刷新页面。两个表格都填好了,就不一样了。另外,如果将“return Page()”替换为“return Redirect(“/Index”);”,则结果也将是准确的。

    当你提交表格时, return Page() 在文章的上下文中呈现页面。另一方面,当刷新或重定向时,上下文是GET。您看到的差异是因为上下文不同:对POST的响应与对GET的响应不同。

        3
  •  0
  •   AQuirky    7 年前

    正确的。经过很长时间的思考,我终于解决了这个问题。问题是:剃须刀页面以神秘的方式移动,它的神奇之处就表现出来了。

    我最初的假设是错误的。未绕过页模型构造函数。页面模型正由静态值正确构造。但是,在构造之后,页面上的所有绑定对象都将重置。所以这不是一个“无文档的优化”…这是一个无文档的损害。

        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();
        }
    

    这显然是一个巨大的克鲁格,但没有优雅的解决方案存在。有人吗?

    推荐文章