【问题标题】:Html extension needing access to IViewEngine; how?需要访问 IViewEngine 的 HTML 扩展;如何?
【发布时间】:2018-06-25 14:51:12
【问题描述】:

我在将 Html 扩展从 .NET Framework 移植到 .NET Asp.Net Core 时遇到问题!

这是cshtml文件sn-p

    @if (Model.Length == 0)
    {
        WriteLiteral("No current tasks!");
    }
    <section>
        <div class="panel-group" id="accordion-task" role="tablist" aria-multiselectable="true">
            @for (var index = 0; index < Model.Length; index++)
            {
                var task = Model[index];
                var viewName = "_" + task.TaskType;
                var exists = Html.PartialViewExists(viewName);
                var vd = new ViewDataDictionary(ViewData)
            {
                {"index", index}
            };
                vd.Model = task;
                Html.RenderPartial(exists ? viewName : "_Task", task, vd);
            }
        </div>
    </section>

扩展PartialViewExists 扩展消息如下所示:

public static bool PartialViewExists(this HtmlHelper html, string viewName)
{
     var controllerContext = html.ViewContext.Controller.ControllerContext;
     var result = ViewEngines.Engines.FindPartialView(controllerContext, viewName);
     return result.View != null;
}

将其转换为 .net 核心似乎会带来许多问题。

  1. ViewContext 属性没有悬挂控制器。所以 我无法访问 ControllerContext
  2. 即使我有一个 ControllerContext 我仍然需要一个 IViewEngine 似乎只能通过依赖注入获得

我在扩展中看不到这样做的方法,但很想被证明是错误的(依赖注入很好,但可能太过分了!)

谢谢

斯蒂芬

【问题讨论】:

    标签: c# razor asp.net-core


    【解决方案1】:

    这是完全未经测试的代码,但如果它不工作,如果仍然应该给你足够的工作。

    第一个问题是您需要知道控制器名称,您可以从 html.ViewContext.ActionDescriptor.RouteValues 集合中获得。

    其次,要获得视图引擎,因为您使用的是静态方法,所以您没有可依赖的自动依赖注入,因此您需要求助于更老套的服务定位器模式。

    //Some imports...
    using Microsoft.AspNetCore.Mvc.Rendering;
    using Microsoft.AspNetCore.Mvc.ViewEngines;
    
    public static bool PartialViewExists<TModel>(this IHtmlHelper<TModel> html, string viewName)
    {
        var controller = html.ViewContext.ActionDescriptor.RouteValues["controller"];
    
        var viewEngine = (ICompositeViewEngine)html.ViewContext.HttpContext.RequestServices
            .GetService(typeof(ICompositeViewEngine));
    
        var result = viewEngine.GetView(html.ViewContext.ExecutingFilePath, viewName, false);
        return result.View != null;
    }
    

    这对我说的是,也许您不应该为此使用静态助手。最好创建一个适当地利用完整 DI 框架并且您可以测试的适当服务。

    【讨论】:

    • David 谢谢你,今天我会看一下,看看我能不能让它工作......不胜感激。
    • 使用完整的 DI 框架引用您的评论,这是一个现有的应用程序,这将意味着大量重写并且是重构的反模式。对新方法进行如此小的和增量的更改:)
    猜你喜欢
    • 1970-01-01
    • 2012-07-22
    • 1970-01-01
    • 2016-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-26
    相关资源
    最近更新 更多