Due*_*ctu 33 asp.net-core-mvc asp.net-core
我想像在MVC中一样创建自定义HTML Helper,但我找不到如何以正确的方式制作.
我找到了如何创建自定义标记助手但没有HTML助手.
谢谢你的时间!
dou*_*ald 45
对我来说,我认为我的HTML助手没有工作,直到我发现扩展方法现在IHtmlHelper没有HtmlHelper.
所以对于.net核心:
public static IHtmlContent CheckboxListFor<TModel>(this IHtmlHelper<TModel> html,
            Expression<Func<TModel, List<CheckboxListItem>>> expression) ...
Run Code Online (Sandbox Code Playgroud)
而不是.net:
public static HtmlString CheckboxListFor<TModel>(this HtmlHelper<TModel> html,
            Expression<Func<TModel, List<CheckboxListItem>>> expression) ...
Run Code Online (Sandbox Code Playgroud)
编辑:我还将.net核心的返回类型更新为IHtmlContent,因为使用类似于编写HtmlContentBuilder HTML内容并返回返回的更好方法IHtmlContent
Aka*_*oni 38
HTML Helper看起来在ASP.NET Core中受支持,正在等待文档:
https://docs.microsoft.com/en-au/aspnet/core/mvc/views/html-helpers
查看ASP.NET Core源代码,它们与旧版本的ASP.NET MVC非常相似:
MyHTMLHelpers.cs:
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using System;
namespace MyApp.Helpers
{
    public static class MyHTMLHelpers
    {
        public static IHtmlContent HelloWorldHTMLString(this IHtmlHelper htmlHelper)
            => new HtmlString("<strong>Hello World</strong>");
        public static String HelloWorldString(this IHtmlHelper htmlHelper)
            => "<strong>Hello World</strong>";
    }
}
Run Code Online (Sandbox Code Playgroud)
_ViewImports.cshtml(第二行是重要的变化):
@using MyApp
@using MyApp.Helpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Run Code Online (Sandbox Code Playgroud)
MyView.cshtml:
<div>@Html.HelloWorldHTMLString()</div>
<div>@Html.HelloWorldString()</div>
Run Code Online (Sandbox Code Playgroud)
输出:
你好,世界
<strong> Hello World </ strong>
这是使用 TagBuilders 的 .Net Core 2 示例
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.IO;
public static IHtmlContent HelloWorld(this IHtmlHelper html, string name)
{
    var span = new TagBuilder("span");
    span.InnerHtml.Append("Hello, " + name + "!");
    var br = new TagBuilder("br") {TagRenderMode = TagRenderMode.SelfClosing};
    string result;
    using (var writer = new StringWriter())
    {
        span.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default);
        br.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default);
        result = writer.ToString();
    }
    return new HtmlString(result);
}
Run Code Online (Sandbox Code Playgroud)
        好吧,我想这个答案不会被注意到,但这是我使用服务注册想到的:
我希望它能帮助某人。
注册服务:
services.AddTransient<IHtmlHelperFactory, HtmlHelperFactory>();
Run Code Online (Sandbox Code Playgroud)
使用服务:
var helper = HttpContext.RequestServices.GetRequiredService<IHtmlHelperFactory>().Create();
Run Code Online (Sandbox Code Playgroud)
界面:
public interface IHtmlHelperFactory
{
    IHtmlHelper Create();
}
Run Code Online (Sandbox Code Playgroud)
执行:
public class HtmlHelperFactory : IHtmlHelperFactory
{
    private readonly IHttpContextAccessor _contextAccessor;
    public class FakeView : IView
    {
        /// <inheritdoc />
        public Task RenderAsync(ViewContext context)
        {
            return Task.CompletedTask;
        }
        /// <inheritdoc />
        public string Path { get; } = "View";
    }
    public HtmlHelperFactory(IHttpContextAccessor contextAccessor)
    {
        _contextAccessor = contextAccessor;
    }
    /// <inheritdoc />
    public IHtmlHelper Create()
    {
        var modelMetadataProvider = _contextAccessor.HttpContext.RequestServices.GetRequiredService<IModelMetadataProvider>();
        var tempDataProvider = _contextAccessor.HttpContext.RequestServices.GetRequiredService<ITempDataProvider>();
        var htmlHelper = _contextAccessor.HttpContext.RequestServices.GetRequiredService<IHtmlHelper>();
        var viewContext = new ViewContext(
            new ActionContext(_contextAccessor.HttpContext, _contextAccessor.HttpContext.GetRouteData(), new ControllerActionDescriptor()),
            new FakeView(),
            new ViewDataDictionary(modelMetadataProvider, new ModelStateDictionary()),
            new TempDataDictionary(_contextAccessor.HttpContext, tempDataProvider),
            TextWriter.Null,
            new HtmlHelperOptions()
        );
        ((IViewContextAware)htmlHelper).Contextualize(viewContext);
        return htmlHelper;
    }
}
Run Code Online (Sandbox Code Playgroud)
        我永远无法让 HtmlHelper 扩展方法工作,我总是收到:
“IHtmlHelper”不包含“ MethodName ”的定义,并且找不到接受“IHtmlHelper”类型的第一个参数的扩展方法“ MethodName ”(您是否缺少 using 指令或程序集引用?)
即使我的_ViewImports.cshtml文件中有正确的命名空间。所以我决定现在使用 Razor 页面的能力来支持已经注册为依赖注入的注入服务。例如,我需要将一些值从我的配置文件注入到我的_Layout.cshtml文件中。所以我做了以下事情:
1)定义了一个IConfigurationHelperService接口:
public interface IConfigurationHelperService
{
    string GetApiUrl();
}
Run Code Online (Sandbox Code Playgroud)
2)在 ConfigurationHelperSerivce 类(它本身使用依赖注入来获取常规配置类)中定义了该接口的实现:
 public class ConfigurationHelperService : IConfigurationHelperService
 {
    public ConfigurationHelperService(IConfiguration configuration)
    {
        Configuration = configuration;
    }
    private IConfiguration Configuration { get; }
    public string GetApiUrl()
    {
        return GetConfigurationValue(ApiUrl);
    }
    private string GetConfigurationValue(string key)
    {
        var value = Configuration[key];
        if (value.IsNullOrEmpty()) throw new KeyNotFoundException($"Configruation does not contain an instance of {key}");
        return value;
    }
}
Run Code Online (Sandbox Code Playgroud)
3)通过Startup.cs中的ConfigureServices注册注入服务:
public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IConfigurationHelperService, ConfigurationHelperService>();
    services.AddMvc();
}
Run Code Online (Sandbox Code Playgroud)
4) 将正确的命名空间作为 using 语句添加到我的_ViewImports.cshtml文件中。
5) 使用@inject关键字来定义它以在_Layout.cshtml文件中使用。
@inject IConfigurationHelperService ConfigHelper
<!DOCTYPE html>
<html>
...
@ConfigHelper.GetApiUrl()
...
</html>
Run Code Online (Sandbox Code Playgroud)
它对我很有用,我可以在更简单的页面上看到更多的用途,在这些页面上定义模型工作量太大。
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           30809 次  |  
        
|   最近记录:  |