Usando HtmlHelper en un controlador

¿Es posible utilizar HtmlHelper en un controlador, por ejemplo para obtener el método TextBox (…)? no es que no pueda escribir el html que me genera, pero solo quiero entender cómo funciona para poder crear la mejor solución.

Aquí hay un ejemplo adaptado de esto :

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

Tenga en cuenta que esto es un truco, se puede hacer, pero no creo que haya una buena razón para hacer esto …

Puedes usar un método como este:

 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(); } } 

El HtmlHelper es parte del mecanismo de Vista por diseño y se debe considerar por separado para las partes de Controlador y Modelo de MVC. No estoy seguro de por qué querría generar controles dentro del controlador ya que su función es entregar los datos a la vista para su renderizado.

No digo que no puedas lograrlo, pero para un buen diseño sería mejor.

¿Puedes explicar lo que estás tratando de lograr y luego podríamos verlo haciendo de una “manera MVC”?

 using System.Web.Mvc; using System.Web.Mvc.Html; var h = new HtmlHelper(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) 

Para .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 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); } } } 

Asegúrese de registrarse en los servicios:

 services.AddSingleton(); 

Si alguien intenta hacer esto sin un Controlador (como cuando se realizan pruebas unitarias), hay otros problemas con los que lidiar, ya que muchos de estos métodos (que sé que no eran un escenario de prueba, sino para ese escenario) arrojaban Null excepciones ( ViewContext.ScopeCache ). Puede ver esto de la siguiente manera (tenga en cuenta que todas estas formas requieren la ViewContext una instancia de ViewContext , que es uno de los parámetros que inserta en el constructor de la instancia de HtmlHelper, por lo que en ese objeto):

 viewContext.UnobtrusiveJavaScriptEnabled = false; 

Simplemente establecer ese valor arroja una excepción con muchos de estos métodos, pero el problema fue solucionado por esta respuesta , vea cómo obtiene un HtmlHelper (vea también aquí ).

  • usando System.Web.Mvc;
  • utilizando 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());