我已经在我的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中找到连接字符串。
答案 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;
}
}