ASP.NET Get 和 Post 错误验证之间的核心持久值

ASP.NET core persisting values between Get and Post error validation

我是网络开发的新手,所以我不知道如何在请求之间保留数据的好方法。

到目前为止,这是我的网站:

根据 titleId 查询参数,正在从 GET 请求的 API 中获取大象标题。当我按下登录时,模型验证正在 运行,例如必须输入电子邮件和密码。但是,当返回错误页面时,大象文本为空,因为该值未保留。保留该值以便在返回 POST 错误时仍然可见的最佳方法是什么?它是否必须包含在 POST 数据中?我不想再次请求 API。

后面的代码:

public class IndexModel : PageModel
{
    private string apiTitle;
    public string ApiTitle { get { return apiTitle; } set { apiTitle = value;  } }

    // Bind form values
    [BindProperty]
    public User user { get; set; }

    public Task<IActionResult> OnGetAsync(string titleId)
    {
        if (!string.IsNullOrEmpty(titleId))
        {
            ApiTitle = await GetTitleFromApiAsync(titleId);
        }
        return Page();
    }

    public async Task<IActionResult> OnPostLoginAsync()
    {
        if (!IsLoginFormValid())
        {
            // When this is returned, for example if no password was entered,
            // elephant title goes missing since apiTitle is null?
            return Page();
        }

        var user = await LoginEmailAsync();
        return RedirectToPage("/Profile");
    }
}

Html:

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<link rel="stylesheet" href="css/index.css">

<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>

<div class="login-page">

    <span id="label_api_title">@Model.ApiTitle</span>

    <div class="form">
        <form class="login-form" method="post" asp-page-handler="Login">
            <input type="text" placeholder="Email" asp-for="User.Email"/>
            <span asp-validation-for="User.Email" class="text-danger"></span>
            <input type="password" placeholder="Password" asp-for="User.Password1" />
            <span asp-validation-for="User.Password1" class="text-danger"></span>
            <button>login</button>
            <p class="message">Not registered? <a href="#">Create an account</a></p>
        </form>
    </div>
</div>

<script src="js/index.js"></script>

可能是因为您没有在剃须刀中将其发送到您的表单中,并且它仅在获取请求中而不是在 post 请求中发送:

public Task<IActionResult> OnGetAsync(string titleId)//<----its here
    {
        if (!string.IsNullOrEmpty(titleId))
        {
            ApiTitle = await GetTitleFromApiAsync(titleId);
        }
        return Page();
    }

//-->需要在post

中传递title id
public async Task<IActionResult> OnPostLoginAsync(string titleId)
{



 if (!string.IsNullOrEmpty(titleId))
        {
            ApiTitle = await GetTitleFromApiAsync(titleId);
        }

    if (!IsLoginFormValid())
    {
        // When this is returned, for example if no password was entered,
        // elephant title goes missing since apiTitle is null?
        return Page();
    }

    var user = await LoginEmailAsync();
    return RedirectToPage("/Profile");
}

然后在你的剃刀中添加以下形式的跨度:

 <span id="label_api_title">@Model.ApiTitle</span>   
<div class="form">
        <form class="login-form" method="post" asp-page-handler="Login">
         <span id="label_api_title">@Model.ApiTitle</span>/*<--------here*/
        <input type="text" placeholder="Email" asp-for="User.Email"/>
        <span asp-validation-for="User.Email" class="text-danger"></span>
        <input type="password" placeholder="Password" asp-for="User.Password1"/>
        <span asp-validation-for="User.Password1" class="text-danger"></span>
        <button>login</button>
        <p class="message">Not registered? <a href="#">Create an account</a></p>
    </form>

是的。您看到的是预期的行为。请记住,Http 是无状态的。您正在进行 2 个单独的 http 调用,一个用于 GET,一个用于 POST。第二次调用不知道第一次调用做了什么(甚至根本没有第一次调用!)

如果你想有一种方法来读取 Post 调用中的 ApiTitle 属性 值并 return 到视图,你需要坚持它某处,以便它在 http 调用之间可用。但在你的情况下,你所需要的只是将它包含在 post 的形式中,并让框架为你绑定它。

在你的情况下,你可以简单地使用 public 属性 (这是可设置和可获取的)。无需保留私有变量。用 BindProperty 属性装饰你的 属性,这样模型绑定器就会绑定这个 属性.

上的数据
public class CreateModel : PageModel
{
    [BindProperty]
    public string ApiTitle { get; set; }

    //Your existing code goes here
}

现在在您的表单标签中,为 ApiTitle 添加一个隐藏的输入元素。这样,当提交表单时,ApiTitle 属性 的值将在请求数据中发送。

<form class="login-form" method="post" asp-page-handler="Login">
     <input type="hidden" asp-for="ApiTitle"/>
     <input type="text" placeholder="Email" asp-for="User.Username"/>
     <!--Your other existing form elements -->
     <button>login</button>
</form>

现在,在您的 OnPostLoginAsync 方法中,您可以根据需要读取 ApiTitle 值。当您 return 页面(验证失败时)时,UI 将在您的 span 元素中显示 ApiTitle 属性 值。

public async Task<IActionResult> OnPostLoginAsync()
{
    var title  = this.ApiTitle;  // If you want to read this value

    if (!ModelState.IsValid)
    {
        return Page();
    }
    return RedirectToPage("/Profile");
}