REM*_*ESQ 1 c# razor razor-pages
我通常对在 Razor Pages 中使用某些 C# 返回类型的“为什么”(而不是“如何”)感到困惑。在某些情况下,我理解“为什么”,但不清楚何时应该使用一个而不是另一个。我最初的困惑始于异步类型,但现在我明白了。这也加剧了void类型,我对它有了更好的理解,但仍然没有完全理解。
我正在研究几个不同的代码片段以更好地掌握,并且可以使用一些有用的解释 - 文档和其他来源并没有真正为我带回家。
有些方法来自某些 DI,不一定相关(我认为,就我所知,这是使用一种返回类型而不是另一种返回类型的原因,在这种情况下,我感谢解释)。这里有一些不同的片段,我希望社区可以帮助我更好地理解“为什么”使用一种返回类型而不是另一种返回类型(或者我是否应该坚持使用一种类型,因为它不会影响结果正在做什么)。
第一的:
public void OnGet()
{
ServicesContainer = _helper
.GetRecentContentItemsByContentTypeAsync("Services")
.GetAwaiter()
.GetResult()
.SingleOrDefault();
ServicesList = _helper
.GetRecentContentItemsByContentTypeAsync("Service")
.GetAwaiter()
.GetResult()
.OrderByDescending(c => c.CreatedUtc)
.Take(3);
}
Run Code Online (Sandbox Code Playgroud)
代码本身我理解没有问题 - 它正在检索容器和其中的列表项。我的 Razor 页面只是使用重复foreach循环显示列表项。我也了解代码正在获取此信息,这是最基本的示例。所以在我的理解中没有问题。
第二:
public async Task OnGetAsync(string projectTitle)
{
Project = _helper
.QueryContentItemsAsync(q => q
.Where(c => c.DisplayText == projectTitle))
.GetAwaiter()
.GetResult()
.SingleOrDefault();
var relatedProjects =
(IEnumerable<string>)Project?
.Content
.Project.RelatedProjects?
.ContentItemIds?.ToObject<string[]>();
if (relatedProjects?.Count() > 0)
{
RelatedProjects = await
_helper.GetContentItemsByIdAsync(relatedProjects);
}
}
Run Code Online (Sandbox Code Playgroud)
上面还检索了一个可能有项目(RelatedProjects)的“容器”,但在这种情况下,它的做法有点不同,因为除了项目本身之外,可能没有任何要列出的内容。但为什么它使用Task而不是仅仅OnGet?
第三:
public async Task<IActionResult> OnGet()
{
HeaderInfo = await _helper
.GetContentItemByAliasAsync("alias:fullwidth");
return Page();
}
Run Code Online (Sandbox Code Playgroud)
这里只是一个项目。但同样,当所有其他代码不需要返回页面时,为什么要使用Task以及为什么<IActionResult>要返回页面?为什么不使用OnGetAsync?
任何项目都没有什么特别之处——它们都存储在 CMS 上(例如,它们没有任何动态)。第一个,一个包含列表项的容器。第二个是具有潜在相关项目的项目(如果它们存在于 CMS 中,则它们不存在)。第三个只是一个项目。
以及为什么使用 void在第一个上而不是
提前感谢您分享任何见解。
Run Code Online (Sandbox Code Playgroud)public async Task<IActionResult> OnGet() { HeaderInfo = await _helper .GetContentItemByAliasAsync("alias:fullwidth"); return Page(); }
您实际上不需要从此方法返回任何内容。你可以很容易地写出
public async Task OnGet()
{
HeaderInfo = await _helper
.GetContentItemByAliasAsync("alias:fullwidth");
}
Run Code Online (Sandbox Code Playgroud)
调用该Page()方法时,将显示当前页面。如果没有指定其他返回类型,则在任何情况下都会隐式发生这种情况。
通常,您只会将Page()方法作为多种可能的返回类型之一来调用,其中其他返回类型是 IActionResults。最常见的示例是发布表单时:
public IActionResult Create()
{
if(ModelState.IsValid)
{
return RedirectToPage("Success"); // redirect as part of PRG
}
else
{
return Page(); // redisplay the page with validation errors
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您必须声明返回类型(而不是 void 或 Task),因为您要使用 RedirectToPage 方法,该方法返回 RedirectToResult(IActionResult 的类型)。您还必须在这种情况下提供合适的返回类型else,因此调用return Page().
每当向 发出请求时OnGet(),IIS 必须等待数据返回,然后才能处理其他请求。通过使OnGet()异步,这允许 IIS 在等待您的数据返回时执行其他任务。这减少了瓶颈,并使 IIS 执行得更快、更高效。
每当一个方法被标记为 时async,它必须返回一个Task对象。如果您的方法没有什么可返回,那么它仍然必须标记为Task OnGetAsync()。如果您的方法确实返回一个值,您可以在Task对象中指定返回类型,如Task<IActionResult> OnGetAsync().
所以对于你的方法,这是发生了什么:
public void OnGet()
{
// Synchronous method that returns nothing
// IIS stops handling requests here until your method returns
}
public async Task OnGetAsync(string projectTitle)
{
// Asynchronous method that returns nothing.
// When your code reaches the await keyword,
// IIS resumes handling other tasks while awaiting
// for your method to return
}
public async Task<IActionResult> OnGet()
{
// Asynchronous method that returns an IActionResult value
// When your code reaches the await keyword,
// IIS resumes handling other tasks while awaiting
// for your method to return
}
Run Code Online (Sandbox Code Playgroud)