gpt4 book ai didi

c# - ASP.NET Core Razor Pages - 复杂模型属性在返回 Page() 后为空

转载 作者:行者123 更新时间:2023-12-05 09:35:04 26 4
gpt4 key购买 nike

我显然不了解有关 Razor Pages 中模型绑定(bind)复杂属性的一些基本知识。当我的模型无效时,我 return Page(); 但在引用模型的复杂属性时出现异常。这是我的精简版:

模型:

public class Movie
{
public int Id { get; set; }
public string Title { get; set; }
public Director Director { get; set; }
public string Description { get; set; }
}

public class Director
{
public int Id { get; set; }
public string Name { get; set; }
}

Index.cshtml.cs:

[BindProperty]
public Movie Movie { get; set; }

[BindProperty, Required]
public string Description { get; set; }

public IActionResult OnGet()
{
// Pretend we're loading from the DB...
Movie = new Movie
{
Id = 1,
Title = "Citizen Kane",
Director = new Director
{
Id = 101,
Name = "Orson Wells"
}
};

return Page();
}

public IActionResult OnPost()
{
if (!ModelState.IsValid)
return Page();

Movie.Description = Description;

//Save to DB
// ...

return RedirectToPage("/Index");
}

索引.cshtml:

@page
@model IndexModel

<h5>@Model.Movie.Title</h5>
<h6>Directed by @Model.Movie.Director.Name</h6>

<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Movie.Id" />
<textarea asp-for="Description" placeholder="Enter Description"></textarea>
<button type="submit">Submit</button>
</form>

当我将 Description 留空时,模型在 OnPost 中无效并按预期返回 Page()。但是后来我得到一个 System.NullReferenceException;对象引用未设置到对象的实例 此处:

<h6>Directed by @Model.Movie.Director.Name</h6>

为什么 Movie.Director 在这里是空的?返回Page()时需要重新获取数据吗?我原以为它会再次触发 OnGet() 但它没有。我做错了什么?

最佳答案

Why is Movie.Director null here? Do I have to get the data again when returning Page()? I was thinking it would fire OnGet() again but it doesn't.

不,OnGet 方法不会在您的 OnPost 方法实际执行时自动调用。这两个处理程序彼此独立,它们唯一共享的是底层 Razor View 和页面模型。如果您的 View 需要将数据加载到您的模型中,那么您也需要为 OnPost 执行此操作。

可以从您的 POST 方法中调用 GET 方法,但是根据您在 OnGet 中实际执行的操作,这可能会覆盖已明确设置的数据OnPost。相反,我建议添加一个额外的方法,该方法将由 OnGetOnPost 调用,以设置您的 View 的共享模型属性需要渲染。

public IActionResult OnGet()
{
Movie = LoadMovie();
return Page();
}

public IActionResult OnPost()
{
if (!ModelState.IsValid)
{
Movie = LoadMovie();
return Page();
}

// …
return RedirectToPage("/Index");
}

private Movie LoadMovie()
{
// …
}

请注意,如果您确实需要呈现您的页面 View ,您也只需要执行此方法。


混淆可能源于 OnGetOnPost 方法的用途:对于 Razor 页面,这些方法是入口点。当请求与 Razor 页面匹配的路由时,ASP.NET Core 框架会调用它们。如果是 GET 请求,则调用 OnGet 方法;如果是 POST 请求,则为 OnPost 方法。除了共享相同的 View (cshtml)和模型之外,这些方法之间没有直接关系。

由于这些方法是入口点,POST 请求不会执行 OnGet 方法,GET 请求也不会执行 OnPost 方法——当然,除非您那些在这些方法中调用你自己。

现在,当您返回 Page() 时,唯一发生的事情就是您告诉 ASP.NET Core 框架然后使用您在页面模型中准备的数据呈现您的 Razor View .所以它只是渲染 cshtml 传递页面模型作为 View 的模型。然而,此时这不会导致对 OnGetOnPost 的任何调用,因为它们已经运行以进入 Razor 页面执行。

这意味着如果您想始终在呈现 View 之前执行某些逻辑,那么您需要在返回 Page() 之前从您的页面处理程序中显式执行该逻辑。

关于c# - ASP.NET Core Razor Pages - 复杂模型属性在返回 Page() 后为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66142081/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com