【问题标题】:Can I render another partial view in a partial view by specifying relative path with Razor Pages?我可以通过使用 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

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


【解决方案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());
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-12
      • 1970-01-01
      相关资源
      最近更新 更多