Можно ли использовать HtmlHelper в контроллере, например, чтобы получить метод TextBox (...)? не то, что я не могу написать html, который он генерирует сам, но я просто хочу понять, как это работает, чтобы я мог создать наилучшее решение.
Использование HtmlHelper в контроллере
Ответ 1
Здесь приведен пример из this:
var h = new HtmlHelper(new ViewContext(ControllerContext, new WebFormView("omg"), new ViewDataDictionary(), new TempDataDictionary()), new ViewPage());
h.TextBox("myname");
Обратите внимание, что это взломать, это можно сделать, но я не думаю, что есть веские причины для этого...
Ответ 2
Вы можете использовать такой метод:
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();
}
}
Ответ 3
HtmlHelper является частью механизма просмотра по дизайну и должен рассматриваться отдельно от частей контроллера и модели MVC. Я не уверен, почему вы хотите генерировать элементы управления внутри контроллера, поскольку роль заключается в доставке данных в представление для рендеринга.
Я не говорю, что вы не можете этого достичь, но для хорошего дизайна было бы лучше.
Можете ли вы объяснить, что вы пытаетесь достичь, и тогда мы могли бы посмотреть на это с помощью "способа MVC"?
Ответ 4
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)
Ответ 5
Для.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>();
Ответ 6
Если кто-то пытается это сделать без контроллера (например, при модульном тестировании), возникают дополнительные проблемы, так как многие из этих методов (которые, как я знаю, не были сценарием тестирования, но для этого сценария) бросали Null исключения (ViewContext.ScopeCache
). Вы можете видеть это следующим образом (обратите внимание, что все эти способы требуют создания экземпляра ViewContext
, который является одним из параметров, которые вы вставляете в конструктор экземпляра HtmlHelper, и так на этом объекте):
viewContext.UnobtrusiveJavaScriptEnabled = false;
Просто установка этого значения вызывает исключение со многими из этих методов, но проблема была исправлена для меня этим ответом, см., как он получает HtmlHelper
( см. также здесь).
Ответ 7
- с использованием System.Web.Mvc;
-
используя System.Web.Mvc.Html;
HtmlHelper helper = new HtmlHelper(new ViewContext(ControllerContext, new WebFormView(ControllerContext, "Index"), new ViewDataDictionary(), new TempDataDictionary(), new System.IO.StringWriter()), new ViewPage());