ASP.NET Core 2.0中的部分页面

时间:2017-08-17 19:48:19

标签: c# razor asp.net-core asp.net-core-mvc .net-core

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

我一直在搞乱ASP.NET 2.0的新Razor Page功能,并且在部分方面遇到了一些麻烦。上面链接的文档是指" partials"在几个地方,但只是在说一些神秘的东西,比如"您使用MVC控制器和传统Razor视图的布局,模板和部分只是工作。&# 34;他们的意思是partial Views,就像我们习惯的那样,还是一些新的部分页面?它们表明名称中带有常规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>
    
  • 同一目录中名为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; }
        }
    }
    
  • 同一目录中名为DerpWrapper.cshtml的第二个页面文件,其代码如下:

    @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)
    
  • 当然是_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)
    ...

为什么&#34;包装&#34; Page&#39; s Model等于null?是否无法定义Razor页面并使用Html.Partial()从其他页面或视图中显示它?

2 个答案:

答案 0 :(得分:7)

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

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

Razor中存在的其他可重用组件是view components。视图组件与partials类似,但它们具有支持它们的实际类,并允许您将自己的逻辑添加到视图组件。

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

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

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

答案 1 :(得分:0)

堆栈溢出的答案存在很长一段时间,因此确保它们得到改善很重要。

添加到Poke的答案中或更正。部分视图将页面之间的公共部分分开。 这些部分可以包含逻辑。但是该逻辑不应涉及任何特定页面中包含或定义的任何字段(变量或对象)。他们可以通过依赖注入将逻辑注入到局部视图中。