在asp.net核心中合并HtmlAttributes

时间:2017-05-13 06:19:41

标签: asp.net-core-1.1

我已经在我的asp.net mvc 5编辑器模板中使用了Chris Pratt的MergeHtmlAttributes Html Helper Extension方法一段时间了。我开始将应用程序切换到Asp.net核心1.1(.net framework 4.5.2)。并且htmlhelperExtension对我不起作用。

public static partial class HtmlHelperExtensions
{
    //https://cpratt.co/html-editorfor-and-htmlattributes/
    public static IDictionary<string, object> MergeHtmlAttributes(this HtmlHelper helper, object htmlAttributesObject, object defaultHtmlAttributesObject)
    {
        var concatKeys = new string[] { "class" };

        var htmlAttributesDict = htmlAttributesObject as IDictionary<string, object>;
        var defaultHtmlAttributesDict = defaultHtmlAttributesObject as IDictionary<string, object>;

        RouteValueDictionary htmlAttributes = (htmlAttributesDict != null)
            ? new RouteValueDictionary(htmlAttributesDict)
            : HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributesObject);

        RouteValueDictionary defaultHtmlAttributes = (defaultHtmlAttributesDict != null)
            ? new RouteValueDictionary(defaultHtmlAttributesDict)
            : HtmlHelper.AnonymousObjectToHtmlAttributes(defaultHtmlAttributesObject);

        foreach (var item in htmlAttributes)
        {
            if (concatKeys.Contains(item.Key))
            {
                defaultHtmlAttributes[item.Key] = (defaultHtmlAttributes[item.Key] != null)
                    ? string.Format("{0} {1}", defaultHtmlAttributes[item.Key], item.Value)
                    : item.Value;
            }
            else
            {
                if(item.Key?.ToString() == "divClass")
                {
                    continue;
                }
                defaultHtmlAttributes[item.Key] = item.Value;
            }
        }

        return defaultHtmlAttributes;
    }
}

当我复制该类时,标记该语句:using System.Web.Mvc; - 不解析符号MVC。 删除使用语句后,我得到的消息无法解析符号&#34; HtmlHelper&#34;在MergeHtmlAttributes(this HtmlHelper helper, ...) 我可以选择添加其中一个 Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper.HtmlHelper<Tmodel>我选择了.HtmlHelper。 之后它引用了RouteValueDictionary行htmlAttributes =并表示它无法将IDictionary<string, object>转换为system.web.Routing.RouteValueDictionary。我应该将类型更改为IDictionary<string, object>或转换为RouteValueDictionary。无论哪种方式,当我尝试在我的一个编辑器模板中使用MergeHtmlAttributes时,我都会收到以下错误。

'IHtmlHelper<object>'不包含&#39; MergeHtmlAttributes&#39;的定义。和最好的扩展方法重载&#39; HtmlHelperExtensions.MergeHtmlAttributes(HtmlHelper,object,object)&#39;需要一个类型为&#39; HtmlHelper&#39;

的接收器

此行正在抛出错误 - &gt; var htmlAttributes = Html.MergeHtmlAttributes(ViewData, defaultHtmlAttributesObject);

有没有办法让它在asp.net核心中运行,还是有不同的方法来实现相同的结果?这是我的一个编辑器模板的示例,因此您可以看到正在使用的MergeHtmlAttributes。如果我不能再像这样构建模板,那么有更新/更好的方法来使用标记助手吗?我真的很喜欢在一个html助手中使用labelfor,txtboxfor,ValidationMessageFor等。

@model int?

@{
    var defaultHtmlAttributesObject = new { @class = "form-control" };
    var htmlAttributes = Html.MergeHtmlAttributes(ViewData, defaultHtmlAttributesObject);

    object divClass;
    ViewData.TryGetValue("divClass", out divClass);
    if (divClass == null) { divClass = ""; }

    IDictionary<string, object> validationAttributes = Html.GetUnobtrusiveValidationAttributes("");
    Html.ViewContext.FormContext.RenderedField(ViewData.TemplateInfo.GetFullHtmlFieldName(null), false);
}

<div class="form-group @divClass @(Html.ValidationErrorFor(x => x, " has-error"))">
    @Html.LabelFor(x => x, new { @class = "control-label" })
    @if (validationAttributes.ContainsKey("data-val-required"))
    {<span class="text-danger">*</span>}
    @Html.TextBoxFor(x => x, htmlAttributes)
    @Html.ValidationMessageFor(model => model, "", new { @class = "text-danger" })
</div>

F.Y.I。转换到asp.net核心1.1(和.net框架4.5.2)时,我最终将连接字符串放在它的app.config文件中,该文件允许EF6与Asp.net核心一起工作,这样我就可以继续使用我构建的EF代码,无论出于何种原因,它都无法在appsettings.json中找到连接字符串。

1 个答案:

答案 0 :(得分:3)

最初我没有意识到微软现在使用 IHtmlHelper而不是HtmlHelper

一旦我修改了代码以反映该更改并在github 上找到 Microsoft的mvc存储​​库,以便我能够找到它们的AnonymousObjectToHtmlAttributes的实现,它们就全部落在了一起。

以下代码对我有用,但我可能不得不对我尚未想到的边缘情况进行一些更改。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Routing;

using Microsoft.AspNetCore.Mvc.Rendering;

public static class HtmlHelperExtensions
{
    //http://cpratt.co/html-editorfor-and-htmlattributes/
    /// <summary>
    /// This is used with the EditorTemplates to copy the page element's htmlAttributes over to the editorTemplates 
    /// while still being able to specify values to always use (like @class = "form-control") in the editorTemplates.
    /// </summary>
    public static IDictionary<string, object> MergeHtmlAttributes(this IHtmlHelper helper, object htmlAttributesObject, object defaultHtmlAttributesObject)
    {
        var concatKeys = new[] { "class" };

        var htmlAttributesDict = htmlAttributesObject as IDictionary<string, object>;
        var defaultHtmlAttributesDict = defaultHtmlAttributesObject as IDictionary<string, object>;

        RouteValueDictionary htmlAttributes = new RouteValueDictionary(htmlAttributesDict != null
            ? htmlAttributesDict
            : AnonymousObjectToHtmlAttributes(htmlAttributesObject));

        RouteValueDictionary defaultHtmlAttributes = new RouteValueDictionary(defaultHtmlAttributesDict != null
            ? defaultHtmlAttributesDict
            : AnonymousObjectToHtmlAttributes(defaultHtmlAttributesObject));

        foreach (var item in htmlAttributes)
        {
            if (concatKeys.Contains(item.Key))
            {
                defaultHtmlAttributes[item.Key] = defaultHtmlAttributes[item.Key] != null
                    ? string.Format("{0} {1}", defaultHtmlAttributes[item.Key], item.Value)
                    : item.Value;
            }
            else
            {
                if(item.Key == "divClass")
                {
                    continue;
                }
                defaultHtmlAttributes[item.Key] = item.Value;
            }
        }

        return defaultHtmlAttributes;
    }

    private static IDictionary<string, object> AnonymousObjectToHtmlAttributes(object htmlAttributes)
    {
        var dictionary = htmlAttributes as IDictionary<string, object>;
        if (dictionary != null)
        {
            return new Dictionary<string, object>(dictionary, StringComparer.OrdinalIgnoreCase);
        }

        dictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);

        if (htmlAttributes != null)
        {
            var stringAttributes = htmlAttributes.ToString();
            stringAttributes = stringAttributes.Replace("{", "").Replace("}", "");
            string[] attributesArray = stringAttributes.Split(new[] { ','}, StringSplitOptions.RemoveEmptyEntries);

            foreach (var helper in attributesArray)
            {
                string[] attribKeyValue = helper.Trim().Split(' ');
                dictionary[attribKeyValue.First()] = attribKeyValue.Last();
            }
        }

        return dictionary;
    }
}