Использование HtmlHelper в контроллере



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

458   7  

7 ответов:

вот пример, адаптированный из этой:

var h = new HtmlHelper(new ViewContext(ControllerContext, new WebFormView("omg"), new ViewDataDictionary(), new TempDataDictionary()), new ViewPage());
h.TextBox("myname");

обратите внимание, что это хак, это можно сделать, но я не думаю, что есть какие-либо веские причины для этого...

вы можете использовать такой метод:

public static HtmlHelper GetHtmlHelper(this Controller controller)
{
    var viewContext = new ViewContext(controller.ControllerContext, new FakeView(), controller.ViewData, controller.TempData, TextWriter.Null);
    return new HtmlHelper(viewContext, new ViewPage());
}

public class FakeView : IView
{
    public void Render(ViewContext viewContext, TextWriter writer)
    {
        throw new InvalidOperationException();
    }
}

HtmlHelper является частью механизма представления по дизайну и должен рассматриваться отдельно от контроллера и модели частей MVC. Я не уверен, почему вы хотите создавать элементы управления внутри контроллера, поскольку его роль заключается в доставке данных в представление для рендеринга.

Я не говорю, что вы не можете достичь этого, но для хорошего дизайна это было бы лучше.

можете ли вы объяснить, чего вы пытаетесь достичь, а затем мы могли бы посмотреть на это в "MVC путь"?

using System.Web.Mvc;
using System.Web.Mvc.Html;

var h = new HtmlHelper<Effort>(new ViewContext(ControllerContext, new WebFormView(ControllerContext, "omg"), new ViewDataDictionary(), new TempDataDictionary(), new StringWriter()), new ViewPage());

h.DisplayFor(e => Model.Efforts[i].Content.Offer.Price1.Value)

для .NET Core 2 MVC:https://github.com/aspnet/Mvc/issues/7321

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.Options;
using System.IO;
using System.Text.Encodings.Web;
using System.Threading.Tasks;


    public class HelperGenerator
    {
        private readonly IHtmlGenerator _htmlGenerator;
        private readonly ICompositeViewEngine _compositeViewEngine;
        private readonly IModelMetadataProvider _modelMetadataProvider;
        private readonly IViewBufferScope _viewBufferScope;
        private readonly IActionContextAccessor _actionContextAccessor;
        private readonly HtmlHelperOptions _htmlHelperOptions;

        public HelperGenerator(IHtmlGenerator htmlGenerator, ICompositeViewEngine compositeViewEngine, IModelMetadataProvider modelMetadataProvider, IViewBufferScope viewBufferScope, IActionContextAccessor actionContextAccessor, IOptions<MvcViewOptions> options)
        {
            _htmlGenerator = htmlGenerator;
            _compositeViewEngine = compositeViewEngine;
            _modelMetadataProvider = modelMetadataProvider;
            _viewBufferScope = viewBufferScope;
            _actionContextAccessor = actionContextAccessor;
            _htmlHelperOptions = options.Value.HtmlHelperOptions;
        }
        public IHtmlHelper HtmlHelper(ViewDataDictionary ViewData, ITempDataDictionary TempData)
        {
            var helper = new HtmlHelper(_htmlGenerator, _compositeViewEngine, _modelMetadataProvider, _viewBufferScope, HtmlEncoder.Default, UrlEncoder.Default);
            var viewContext = new ViewContext(_actionContextAccessor.ActionContext,
               new FakeView(),
               ViewData,
               TempData,
               TextWriter.Null,
               _htmlHelperOptions);
            helper.Contextualize(viewContext);
            return helper;
        }
        private class FakeView : IView
        {
            public string Path => "View";

            public Task RenderAsync(ViewContext context)
            {
                return Task.FromResult(0);
            }
        }
    }

обязательно зарегистрируйтесь в сервисах:

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

если кто-то пытается сделать это без контроллера (например, при модульном тестировании), есть дополнительные проблемы, с которыми нужно иметь дело, так как многие из этих методов (которые я знаю, не были сценарием тестирования, но для этого сценария) выбрасывали нулевые исключения (ViewContext.ScopeCache). Вы можете увидеть это следующим образом (обратите внимание, что все эти способы требуют ViewContext экземпляр, который будет сформирован, что является одним из параметров, которые вы вставляете в конструктор экземпляра HtmlHelper, так что на этом объекте):

viewContext.UnobtrusiveJavaScriptEnabled = false;

просто установка этого значения вызывает исключение со многими из этих методов, но проблема была исправлена для меня этот ответ, смотрите, как он получает HtmlHelper (см. Также здесь).

  • использование системы.Сеть.Mvc;
  • использование системы.Сеть.Mvc.Html;

     HtmlHelper helper = new HtmlHelper(new ViewContext(ControllerContext, new            WebFormView(ControllerContext, "Index"), new ViewDataDictionary(), new TempDataDictionary(), new System.IO.StringWriter()), new ViewPage());
    

Comments

    Ничего не найдено.