我可以通过使用 Razor Pages 指定相对路径来在局部视图中呈现另一个局部视图吗?

Posted

技术标签:

【中文标题】我可以通过使用 Razor Pages 指定相对路径来在局部视图中呈现另一个局部视图吗?【英文标题】:Can I render another partial view in a partial view by specifying relative path with Razor Pages? 【发布时间】:2022-01-17 02:07:09 【问题描述】:

我有一个 Razor Pages 项目(无控制器),其结构如下:

从主要的Index.cshtml,我会根据主题名称呈现其内容的部分视图,例如:

@* Default will be replaced with theme name *@
<partial name="Themes\Default\HomeContent" />

HomeContent.cshtml 中,我想在其文件夹中呈现许多其他部分视图。但是这行不通:

<p>Content</p>

<partial name="_DefaultThemePartial" />

引擎只搜索这些位置(正确的according to the documentation):

InvalidOperationException:部分视图“_DefaultThemePartial”是 未找到。搜索了以下位置:

/Pages/_DefaultThemePartial.cshtml

/Pages/Shared/_DefaultThemePartial.cshtml

/Views/Shared/_DefaultThemePartial.cshtml

我也尝试过&lt;partial name="./_DefaultThemePartial" /&gt;&lt;partial name=".\_DefaultThemePartial" /&gt; 或尝试将它们放在名为Shared 的子文件夹中(在默认文件夹中)。它们都不起作用,只搜索了上述 3 个位置。

有没有在不指定完整路径的情况下渲染这些部分?

【问题讨论】:

为什么不想给出完整路径? @PoulBak 将来可能会改变,重复硬字符串路径不是一个好主意。 您可能会更改路径以使用变量,您可以在某处全局定义该变量。不理想,但如果需要,您只需更改一个值。 @PoulBak 是的,如果没有更好的解决方案,那是我想到的一件事。最后我认为这不值得,我只是使用我创建的LocationExpander 【参考方案1】:

从我的GitHub issue 的回复中,可以通过在末尾添加.cshtml 来获得更简单的解决方案,无需任何额外代码:

[...] 这是设计使然。部分视图查找有两种方式:

按名称

按文件路径

如果需要,您已经按名称(不带文件扩展名)进行了查找 要使用相对路径,请确保指定文件扩展名。

<partial name="_DefaultThemePartial.cshtml" /> 

【讨论】:

【参考方案2】:

我发布了a proposal here。同时,我发现您可以使用IViewLocationExpander 扩展发现机制,但我几乎没有找到任何有用的文档。

public class PartialViewLocationExpander : IViewLocationExpander

    public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
    
        if (!context.Values.TryGetValue("FromView", out var fromView))
        
            return viewLocations;
        

        var folder = Path.GetDirectoryName(fromView) ?? "/";
        var name = context.ViewName;
        if (!name.EndsWith(".cshtml", StringComparison.OrdinalIgnoreCase))
        
            name += ".cshtml";
        

        var path = Path.Combine(folder, name)
            .Replace('\\', '/');

        return viewLocations.Concat(new[]  path );
    

    public void PopulateValues(ViewLocationExpanderContext context)
    
        var ctx = context.ActionContext as ViewContext;
        if (ctx == null)  return; 

        var path = ctx.ExecutingFilePath;
        if (!string.IsNullOrEmpty(path))
        
            context.Values["FromView"] = path;
            context.Values["ViewName"] = context.ViewName;
        
    


// Register
services.Configure<RazorViewEngineOptions>(options =>

    options.ViewLocationExpanders.Add(new PartialViewLocationExpander());
);

【讨论】:

以上是关于我可以通过使用 Razor Pages 指定相对路径来在局部视图中呈现另一个局部视图吗?的主要内容,如果未能解决你的问题,请参考以下文章

相对页面路径“关于”只能在执行 Razor 页面时使用。指定一个

Razor Pages .NetCore OnPost 处理程序

在使用Razor Pages时你还应该使用控制器吗?

Razor Pages - 由于多个对象共享参数,模型验证失败

如何在 Razor Pages 路由的开头添加应用程序名称?

Core Identity Razor Pages 或直接使用用户/角色/登录管理器