在Controller中使用HtmlHelper

时间:2009-03-07 03:19:46

标签: asp.net-mvc

是否可以在控制器中使用HtmlHelper,例如获取TextBox(...)方法?并不是说我不能写自己生成的html,但我只是想了解它是如何工作的,这样我才能创造出最好的解决方案。

7 个答案:

答案 0 :(得分:41)

以下是改编自this的示例:

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

请注意,这是一个黑客,它可以做,但我认为没有任何理由这样做...

答案 1 :(得分:30)

你可以使用这样的方法:

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

答案 2 :(得分:7)

HtmlHelper是View设计的一部分,应该被视为与MVC的Controller和Model部分分开。我不确定你为什么要在控制器内部生成控件,因为它的作用是将数据传递给视图进行渲染。

我不是说你无法实现它,但是为了好的设计它会更好。

你能解释一下你想要实现的目标吗?然后我们可以用“MVC方式”来看待它吗?

答案 3 :(得分:5)

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)

答案 4 :(得分:1)

对于.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>();

答案 5 :(得分:0)

如果有人在没有控制器的情况下尝试这样做(比如在进行单元测试时),还有其他问题需要处理,因为很多这些方法(我知道,不是测试场景,但对于那种场景)抛出空例外(ViewContext.ScopeCache)。您可以通过以下方式看到这一点(请注意,所有这些方法都需要形成ViewContext实例,这是您插入到HtmlHelper实例的构造函数中的参数之一,因此在该对象上):

viewContext.UnobtrusiveJavaScriptEnabled = false;

简单地设置该值会引发许多这些方法的异常,但问题已为我by this answer修复,看看他是如何获得HtmlHelper的(另请参阅here)。< / p>

答案 6 :(得分:0)

  • 使用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());