63 votes

Utilisation de HtmlHelper dans un contrôleur

Est-il possible d'utiliser HtmlHelper dans un contrôleur, par exemple pour obtenir la méthode TextBox(...) ? Ce n'est pas que je ne puisse pas écrire moi-même le html qu'il génère, mais je veux juste comprendre comment cela fonctionne pour pouvoir créer la meilleure solution.

Merci d'avance !

41voto

Mauricio Scheffer Points 70470

Voici un exemple adapté de ce :

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

Notez que c'est un hack, cela peut être fait mais je ne pense pas qu'il y ait une bonne raison de le faire...

30voto

Vitaliy Ulantikov Points 2834

Vous pouvez utiliser une méthode comme celle-ci :

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

8voto

Richard Points 11249

Le HtmlHelper fait partie du mécanisme de visualisation par conception et doit être considéré comme distinct des parties Contrôleur et Modèle de MVC. Je ne vois pas pourquoi vous voudriez générer des contrôles à l'intérieur du contrôleur, car son rôle est de fournir les données à la vue pour le rendu.

Je ne dis pas que vous ne pouvez pas y arriver, mais pour une bonne conception, ce serait mieux.

Pouvez-vous expliquer ce que vous essayez d'obtenir et nous pourrions alors envisager de le faire à la manière d'un "MVC" ?

5voto

Anubis Points 555
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)

3voto

jonmeyer Points 214

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

Assurez-vous de vous inscrire dans les services :

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X