2017-05-13 12 views
1

Ich habe Chris Pratt MergeHtmlAttributes Html Helper Extension-Methode für eine Weile in meinem asp.net mvc 5 Editor Vorlagen verwendet. Ich habe damit begonnen, eine Anwendung auf Asp.net Core 1.1 (.net Framework 4.5.2) umzustellen. Und die HTMLhelperExtension funktioniert nicht für mich.Merge HtmlAttributes in asp.net Kern

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

Wenn ich die Klasse über kopieren, kennzeichnet die Anweisung: using System.Web.Mvc; -Kann das Symbol MVC nicht auflösen. Und nach dem Entfernen der Anweisung bekomme ich die Meldung nicht Symbol „Htmlhelper“ in MergeHtmlAttributes(this HtmlHelper helper, ...) Ich habe die Möglichkeit der Zugabe von entweder Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper oder .HtmlHelper<Tmodel> Ich wählte .HtmlHelper lösen. Danach verweist es auf die Zeile RouteValueDictionary htmlAttributes = und sagt, dass es IDictionary<string, object> nicht zu system.web.Routing.RouteValueDictionary konvertieren kann. Und ich sollte den Typ zu IDictionary<string, object> ändern oder zu RouteValueDictionary umwandeln. In jedem Fall erhalte ich den folgenden Fehler, wenn ich versuche, MergeHtmlAttributes in einer meiner Editor-Vorlagen zu verwenden.

'IHtmlHelper<object>' keine Definition für ‚MergeHtmlAttributes‘ enthält und die beste Verlängerungs -Methodenüberladung ‚HtmlHelperExtensions.MergeHtmlAttributes (Htmlhelper, Objekt, Objekt)‘ einen Empfänger des Typs ‚Htmlhelper‘ den Fehler wirft erfordert

Diese Linie ->var htmlAttributes = Html.MergeHtmlAttributes(ViewData, defaultHtmlAttributesObject);

Gibt es eine Möglichkeit, dies im asp.net-Kern zu arbeiten oder gibt es eine andere Methode, um die gleichen Ergebnisse zu erzielen? Hier ist ein Beispiel für eine meiner Editor-Vorlagen, damit Sie die verwendeten MergeHtmlAttributes sehen können. Wenn ich das Template nicht mehr so ​​erstellen kann, gibt es einen neueren/besseren Weg, es mit Hilfe von Tags zu machen? Ich mag es wirklich, das labelfor, txtboxfor, ValidationMessageFor usw. in einem HTML-Helfer zu haben.

@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. Beim Konvertieren in asp.net Core 1.1 (und .NET Framework 4.5.2) habe ich die Verbindungszeichenfolge in die app.config-Datei eingefügt, die EF6 erlaubt, mit dem Asp.net-Core zu arbeiten, damit ich den EF-Code, den ich hatte, weiter verwenden kann gebaut, aus irgendeinem Grund würde es die Verbindungszeichenfolge in appsettings.json nicht finden.

+0

ich denke, die Funktionsdefinition sein sollte: public static IDictionary MergeHtmlAttributes (dieses IHtmlHelper Helfer, Objekt htmlAttributesObject, Objekt defaultHtmlAttributesObject) Sobald ich das tun, dann erhalte ich "Kann nicht Symbol lösen AnonymousObjectToHtmlAttributes" in IHtmlHelper.AnonymousObjectToHtmlAttributes (htmlAttributesObject); Ich habe gefunden, wie AnonymousObjectToHtmlAttributes auf Github hier implementiert wurde: https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/HtmlHelper.cs –

Antwort

0

Anfangs war mir nicht klar, dass Microsoft jetzt HTMLHelper anstelle von HtmlHelper verwendete. Sobald ich den Code geändert habe, um diese Änderung widerzuspiegeln und Microsofts mvc-Repository auf github gefunden zu haben, sodass ich ihre Implementierung von AnonymousObjectToHtmlAttributes finden konnte, fiel alles zusammen. Der folgende Code funktioniert für mich, aber ich muss möglicherweise einige Änderungen für Randfälle vornehmen, an die ich noch nicht gedacht habe.

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