Использование HtmlHelper в контроллере - PullRequest
63 голосов
/ 07 марта 2009

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

Ответы [ 7 ]

41 голосов
/ 07 марта 2009

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

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

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

30 голосов
/ 09 января 2011

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

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();
    }
}
7 голосов
/ 08 марта 2009

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

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

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

5 голосов
/ 26 января 2012
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 голос
/ 01 февраля 2018

Для .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>();
0 голосов
/ 05 июня 2017
  • с использованием 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());
    
0 голосов
/ 05 марта 2015

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

viewContext.UnobtrusiveJavaScriptEnabled = false;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...