ASP.NET Core 2.0中的部分页面

3

TL; DR: 在ASP.NET Core 2.0中,是否可以实现“部分页面”?如果可以,为什么会出现下面描述的错误?

我一直在尝试使用ASP.NET 2.0的新特性——Razor Page,但是在使用partials时遇到了一些问题。上面链接的文档在多个地方提到“partials”,但只是神秘兮兮地说了一些话,比如:“与MVC控制器和传统的Razor视图一起使用的布局、模板和partials只需要工作。”他们是指像我们习惯的Partial Views,还是一些新的部分页面?他们显示可以将具有传统Partial后缀名称的文件放置在Pages/文件夹中,但他们提到的文件(例如_ValidationScriptsPartial.cshtml)没有@page声明。如果“部分页面”确实是一个新事物,那么我期望以下最小场景可以正常工作:

  • A Page file named Derp.cshtml:

    @page
    @namespace MyApp.Pages
    @model DerpModel
    
    <p>Member 1: @Model.Member1</p>
    <p>Member 2: @Model.Member2</p>
    
  • A class file named Derp.cshtml.cs in the same directory (nested under the first in VS 2017's Solution Explorer), containing the following class:

    namespace MyApp.Pages {  
        public class DerpModel : PageModel {
            public void OnGet() {
                Member1 = "Derp Member1";
                Member2 = "Derp Member2";
            }
    
            public string Member1 { get; set; }
            public string Member2 { get; set; }
        }
    }
    
  • A second Page file named DerpWrapper.cshtml in the same directory, with the following code:

    @page "{id}"
    @namespace MyApp.Pages
    @model DerpModel
    
    <p>Outer Member 1: @Model.Member1</p>
    <p>Outer Member 2: @Model.Member2</p>
    @Html.Partial("Derp", Model)
    
  • And of course a _ViewImports file that declares @namespace MyApp.Pages

请注意,两个 Razor 页面都有相同的 @model 类型,并且第二个页面基本上通过调用 Html.Partial() 来包装第一个页面并传递其 Model。这应该是非常标准的内容,但当导航到 http://localhost:xxx/DerpWrapper 时,由于 NullReferenceException,我得到了500响应,以下是堆栈跟踪。
    MyApp.Pages.Derp_Page.get_Model()
    MyApp.Pages.Derp_Page+<ExecuteAsync>d__0.MoveNext() in Derp.cshtml
    +
    <p>Inner Member1: @Model.Member1</p>
    ...
    MyApp.Pages.DerpWrapper_Page+<ExecuteAsync>d__0.MoveNext() in DerpWrapper.cshtml
    +
    @Html.Partial("Derp", Model)
    ...

为什么“包装器”页面的Model等于空?是否没有办法定义一个Razor页面并通过Html.Partial()从另一个页面或视图中显示它?

1
我对ASP.NET Core不是很熟悉,但是新的@page指令不会导致页面像一个操作一样吗?这将意味着必须使用子操作来嵌入它,而不是.Partial,但谁知道呢。无论如何,我只会尝试从部分文件Derp.cshtml中删除@page - AaronLS
1
Razor页面的局部页面在这里描述: https://www.learnrazorpages.com/razor-pages/partial-pages省略局部页面的@page将解决nullrefex问题。 - vip32
2个回答

8

Razor的部分视图基本上是.cshtml视图,它们被插入到另一个视图中,即razor视图或razor页面中。它们在该视图中呈现,并因此继承了一些视图的属性,例如其ViewData。但是,它们没有控制器、页面模型或其他一些“代码后台”,这使您无法运行部分的代码。

因此,部分的主要用途是将不包含自己逻辑的常见组件提取到单独且可重用的文件中。

Razor中存在的另一种可重用组件是view components。视图组件类似于部分视图,但它们确实有一个支持它们的实际类,这允许您向视图组件添加自己的逻辑。

目前,视图组件遵循MVC布局,意味着视图组件实际上是一个类,您可以从其Invoke方法返回视图,这会导致视图引擎在Views文件夹中找到该.cshtml文件。然而,David Fowler确认他们正在为视图组件开发Razor页面体验,所以在ASP.NET Core的后续版本中,您最终将能够编写.cshtml视图组件并为其添加一些代码(就像Razor页面一样)。
回到您的问题,目前有两种MVC路由的入口点:MVC控制器(可能返回视图)和Razor页。然而,它们都不能相互调用。如果您要呈现视图,则可以加载部分视图或视图组件,但不能加载其他“完整”视图或Razor页。如果您要呈现Razor页,则也可以加载部分视图或视图组件,但仍然不能加载其他“完整”视图或Razor页。
所以,你想做的事情是不可能的,因为Razor页面应该是路由的入口点,虽然在某些情况下将任何视图作为部分调用可能有效,但你肯定既不会得到该视图的控制器,也不会运行该视图的页面模型。如果你想调用具有复杂逻辑的内容,应该使用视图组件。

感谢您详细的回复!我肯定需要更多地了解ViewComponents,这可能是我正在寻找的东西。在我的项目中混合部分视图和页面似乎有些奇怪。并且因为与Microsoft开发人员勾结而+1! - Rabadash8820

0

Stack Overflow上的答案长期存在,因此确保它们得到改进非常重要。

在Poke的回答基础上补充或更正。部分视图可将页面间的公共部分分离开来。这些部分可以包括逻辑。但是该逻辑不应涉及任何特定页面中包含或定义的字段(变量或对象)。它们可以通过依赖注入应用逻辑...将它们注入到部分视图中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接