是否可以在控制器中使用HtmlHelper,例如获取TextBox(...)方法?并不是说我不能写自己生成的html,但我只是想了解它是如何工作的,这样我才能创造出最好的解决方案。
答案 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.Html;
HtmlHelper helper = new HtmlHelper(new ViewContext(ControllerContext, new WebFormView(ControllerContext, "Index"), new ViewDataDictionary(), new TempDataDictionary(), new System.IO.StringWriter()), new ViewPage());