Razor Pages:对所有返回类型以及何时使用它们感到困惑

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在第一个上而不是

提前感谢您分享任何见解。

Mik*_*ind 6

public async Task<IActionResult> OnGet()
{
    HeaderInfo = await _helper
        .GetContentItemByAliasAsync("alias:fullwidth");

    return Page();
}
Run Code Online (Sandbox Code Playgroud)

您实际上不需要从此方法返回任何内容。你可以很容易地写出

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().


Ice*_*ind 5

每当向 发出请求时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)

  • @REMESQ 如果您需要返回某种 ActionResult,则应该只返回 IActionResult 或 Task&lt;IActionResult&gt; 。理想情况下,您应该具体说明要返回的类型。如果您想显示连接到这些方法所在的 PageModel 的页面,通常不需要返回 IActionResult。如果您想重定向,则需要返回 IActionResult、返回一些 JSON、NotFoundResult 等:https://www.learnrazorpages.com/razor-pages/action-results (2认同)