Расширение HTML, требующее доступа к IViewEngine;как? - PullRequest
0 голосов
/ 25 июня 2018

У меня проблема с переносом расширения Html из .NET Framework в .NET Asp.Net Core!

Это фрагмент файла cshtml

    @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, который кажется доступным только через внедрение зависимостей

Я не вижу способа сделать это в расширении, но хотел бы, чтобы его ошиблись (внедрение зависимостей хорошо, но может зайти слишком далеко!)

Спасибо

Стивен

1 Ответ

0 голосов
/ 25 июня 2018

Это полностью непроверенный код, но если он не работает, он все равно даст вам достаточно для работы.

Первая проблема заключается в том, что вам нужно знать имя контроллера, которое вы получаете из коллекции 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 и который вы сможете протестировать.

...