ASP.NET Core 2.0中的部分页面

Rab*_*820 3 c# razor asp.net-core-mvc .net-core asp.net-core

TL; DR 是否可以在ASP.NET Core 2.0中使用"部分页面"?如果是这样,为什么我会收到下面描述的错误?

我一直在搞乱ASP.NET 2.0 的新Razor Page功能,并且在部分方面遇到了一些麻烦.以上链接的文档是指"谐音"在几个地方,但只说喜欢神秘事物的程度"的布局,模板和你与MVC控制器和传统的剃须刀视图中使用谐音只是工作." 它们是指部分视图,就像我们习惯的那样,还是一些新的部分页面?它们表明Partial名称中带有常规后缀的Pages/文件可以放在文件夹中,但是它们提到的文件(例如_ValidationScriptsPartial.cshtml)没有@page声明.如果"部分页面"确实是一个新东西,那么我希望以下最小方案可以工作:

  • 一个名为的页面文件Derp.cshtml:

    @page
    @namespace MyApp.Pages
    @model DerpModel
    
    <p>Member 1: @Model.Member1</p>
    <p>Member 2: @Model.Member2</p>
    
    Run Code Online (Sandbox Code Playgroud)
  • Derp.cshtml.cs在同一目录中命名的类文件(嵌套在VS 2017的解决方案资源管理器中的第一个目录下),包含以下类:

    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; }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • DerpWrapper.cshtml在同一目录中命名的第二个Page文件,代码如下:

    @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)
    
    Run Code Online (Sandbox Code Playgroud)
  • 当然是一个_ViewImports声明的文件@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)
    ...
Run Code Online (Sandbox Code Playgroud)

为什么"包装器"页面Model等于null?是否无法定义Razor页面并使用其他页面或视图显示它Html.Partial()

pok*_*oke 8

Razor的部分视图基本上.cshtml是被转换为另一个视图的视图,即剃刀视图或剃刀页面.它们该视图中呈现,因此继承了视图的一些属性,例如它ViewData.然而,他们没有控制器,页面模型或其他一些"代码隐藏",它们为您提供了运行部分代码的方法.

因此,partials的主要用途是将不包含逻辑的公共组件提取到单独的和可重用的文件中.

Razor中存在的另一种可重用组件是视图组件.视图组件与partials类似,但它们有一个支持它们的实际类,并允许您将自己的逻辑添加到视图组件.

目前,视图组件遵循视图的MVC布局,这意味着视图组件实际上是一个类,并且您从其Invoke方法返回一个视图,该视图使视图引擎.cshtmlViews文件夹中找到该视图.但是,David Fowler向我确认,他们正在开发Razor页面,就像查看组件的体验一样,所以在ASP.NET Core的更高版本中,您最终将能够编写一个.cshtml视图组件并添加一些代码隐藏它(就像Razor页面一样).

回到你的问题,目前MVC路由有两种入口点:一个MVC控制器,可能返回一个视图,一个Razor页面.但是,这些都不能调用它们中的一个或另一个.如果要渲染视图,则可以加载部分或视图组件,但不能加载其他"完整"视图或Razor页面.如果您要渲染Razor页面,您还可以加载部分或查看组件,但仍然没有其他"完整"视图或Razor页面.

所以你想做的事情根本不可能,因为一个Razor页面应该是路由的入口点,并且当调用任何视图作为部分可能有效时(在某些情况下),你肯定都不会得到控制器查看也不运行页面模型.如果要调用具有复杂逻辑的内容,则应使用视图组件.