【问题标题】:Razor Pages: Confused about all the return types and when to use themRazor Pages:对所有返回类型以及何时使用它们感到困惑
【发布时间】:2019-03-31 13:38:05
【问题描述】:

我通常对在 Razor Pages 中使用某些 C# 返回类型的“为什么”(而不是“如何”)感到困惑。在某些情况下,我理解“为什么”,但不清楚何时应该使用其中一个。我最初的困惑始于异步类型,但现在我明白了。 void 类型也使情况更加复杂,我对它有更好的理解,但还没有完全理解。

我正在研究几种不同的 sn-ps 代码以便更好地掌握,并且可以使用一些有用的解释 - 文档和其他来源并没有真正将它带回家。

某些方法来自某些 DI,并且不一定相关(我认为,据我所知,这是使用一种返回类型而不是另一种返回类型的原因,在这种情况下,我感谢您的解释)。这里有一些不同的 sn-ps,我希望社区可以帮助我更好地理解“为什么”使用一种返回类型而不是另一种(或者我是否应该坚持使用一种类型,因为它不会影响正在做的事情的结果)。

第一:

public void OnGet()
{
    ServicesContainer = _helper
        .GetRecentContentItemsByContentTypeAsync("Services")
        .GetAwaiter()
        .GetResult()
        .SingleOrDefault();
    ServicesList = _helper
        .GetRecentContentItemsByContentTypeAsync("Service")
        .GetAwaiter()
        .GetResult()
        .OrderByDescending(c => c.CreatedUtc)
        .Take(3);
}

代码本身我理解没有问题 - 它正在检索一个容器并列出里面的项目。我的 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);
    }
}

上面还检索了一个可能包含项目(RelatedProjects)的“容器”,但在这种情况下,它的做法有点不同,因为除了项目本身之外可能没有任何东西可以列出。但为什么它使用Task 而不仅仅是OnGet

第三:

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

    return Page();
}

这里只是一个项目。但同样,为什么使用Task 以及为什么在所有其他代码不需要返回页面时使用&lt;IActionResult&gt; 来返回页面?为什么不使用OnGetAsync

任何项目都没有什么特别之处 - 它们都存储在 CMS 上(例如,它们没有动态变化)。第一个,带有列表项的容器。第二个是具有潜在相关项目的项目(如果它们存在于 CMS 中,但它们不存在)。第三个只是一个项目。

为什么在第一个使用void而不是

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

【问题讨论】:

    标签: c# razor razor-pages


    【解决方案1】:

    每当向OnGet() 发出请求时,IIS 必须等待数据返回后才能处理其他请求。通过使OnGet() 异步,这允许IIS 在等待您的数据返回时执行其他任务。这减少了瓶颈,并使 IIS 执行得更快、更高效。

    当一个方法被标记为async 时,它必须返回一个Task 对象。如果你的方法没有返回任何东西,那么它仍然必须标记为Task OnGetAsync()。如果您的方法确实返回了值,您可以在 Task 对象中指定返回类型,如 Task&lt;IActionResult&gt; 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
    }
    

    【讨论】:

    • 清晰简洁。谢谢。跟进:我不清楚我是否可以继续让我的所有代码返回IActionResult,因为似乎两组代码都只是从 CMS 获取信息,而我在 Razor 页面上显示信息.有关系吗?换句话说,第一个或第三个 sn-ps 是否有什么特别之处,需要按照它们的完成方式进行操作?
    • @REMESQ 如果您需要返回某种 ActionResult,您应该只返回 IActionResult 或 Task。理想情况下,您应该具体说明要返回的类型。如果要显示连接到这些方法所在的 PageModel 的页面,通常不需要返回 IActionResult。如果要重定向,则需要返回 IActionResult,返回一些 JSON、NotFoundResult 等:learnrazorpages.com/razor-pages/action-results
    • @MikeBrind “仅应” 通常是基于某种原因。在这种情况下,这个原因是性能?还是只是顺序问题?还是......?
    • @LGSon 仅应说明您的意图。 return Page() 隐含在页面处理程序中。
    • @MikeBrind 谢谢...希望这是原因:)
    【解决方案2】:
    public async Task<IActionResult> OnGet()
    {
        HeaderInfo = await _helper
            .GetContentItemByAliasAsync("alias:fullwidth");
    
        return Page();
    }
    

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

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

    调用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
        }
    }
    

    在这种情况下,您必须声明一个返回类型(而不是 void 或 Task),因为您要使用 RedirectToPage 方法,该方法返回一个 RedirectToResult(一种 IActionResult 类型)。您还必须在 else 情况下提供合适的返回类型,因此调用 return Page()

    【讨论】:

    • 感谢您的洞察力。很有用,因为我计划在其他页面中返回一些 JSON 以及一些表单页面。再次感谢。
    • @remesq 你也可以使用 Web API 返回 JSON learnrazorpages.com/web-api
    猜你喜欢
    • 2016-05-24
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    相关资源
    最近更新 更多