2009-03-07 19 views
62

¿Es posible usar 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.Uso de HtmlHelper en un controlador

Respuesta

39

He aquí un ejemplo adaptado de this:

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

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

+3

no creo que es una cosa fantástica para hacer cualquiera , pero estoy usando controles de cuadrícula de Telerik que usan AJAX, y cuando uso AJAX, el ClientTemplate para una columna debe ser texto renderizado previamente - no podrá res olve la acción en el cliente. Esa es mi razón para buscar esto, en cualquier caso. Preferiría que los controles no funcionaran de esta manera, pero si es el precio que pagué por tener un control de años luz mejor que cualquier cosa que pudiera hacer, entonces es algo que solucionaré. –

+1

este ejemplo no es válido ahora – Anubis

+0

@Anubis: ¿qué quiere decir con 'ahora'? ASP.NET MVC 3? –

7

El HtmlHelper es parte del mecanismo de Vista por diseño y debe considerarse separado de 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 estoy diciendo que no pueda lograrlo, pero para un buen diseño sería mejor.

¿Puede explicar lo que está tratando de lograr y luego podríamos verlo de una manera "MVC"?

+1

Lo estaba usando como una forma de generar el html del control basado en una selección de usuario en una forma ajax. Intentando obtener el mismo concepto que los formularios Rails RJS. Aunque la solución provista funcionó, acepto que esta no es la solución más limpia y, probablemente, terminaré convirtiéndola en parte del cliente. – Gil

30

puede utilizar el método de esta manera:

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

piensa agregar "using System.Web.Mvc.Html;" obtener toda la extensión HtmlHelper (esto es con MVC 3) – Dragouf

+4

Una buena forma de usar htmlhelper en el controlador con mvc 3 es llamar al método parcial para representar html de una vista (por ejemplo, para usar la vista de afeitar como plantilla html email) – Dragouf

+0

Esto es exactamente lo que estaba buscando, funciona como un encanto. Gracias por compartir este código – ViRuSTriNiTy

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) 
+1

esto me ayudó. –

+0

el único que realmente funcionó en un tiempo aquí – matthy

0

Si alguien está tratando de hacer esto desde sin un controlador (como cuando la unidad de pruebas), hay más problemas para hacer frente, ya que muchos de estos métodos (que yo sé, no eran un escenario de prueba, sino para ese escenario) arrojaban excepciones nulas (ViewContext.ScopeCache). Esto se puede ver por la siguiente (tenga en cuenta todos estos aspectos requieren una instancia ViewContext a formar, que es uno de los parámetros se insertan en el constructor de la instancia 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 se solucionó para mí by this answer, vea cómo obtiene un HtmlHelper (vea también here).

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

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

Asegúrese de registrar en los servicios:

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>(); 
Cuestiones relacionadas