2017-06-29 2 views
1

Nous construisons une bibliothèque de classes qui fournit certains types structurés pour le modèle de vue, par ex. InlineImage.Sortie par défaut pour DisplayTemplate d'une classe

Je dois être en mesure de définir la sortie HTML par défaut pour un tel exemple lorsqu'il est utilisé avec @ Html.DisplayFor (...), essentiellement ...

  • Lorsque /Views/DisplayTemplates/InlineImage.cshtml est disponible, utilisez ce modèle
  • Lorsqu'ils ne sont pas disponibles, il devrait afficher la valeur par défaut

Mais ...

  • Quand j'Override juste toString() de cette classe, il me donne la sortie correcte, mais il obtient HTML codé

J'ai découvert l'analyse du code source MVC que je suis capable de désactiver le codage en ajoutant [DisplayFormat (HtmlEncode = false)] à la CLASSE

MAIS ... l'attribut ne cible pas la classe, donc je le bidouille en l'enveloppant dans un autre attribut que j'ajoute à la classe. Il est méchant, mais fonctionne au moins :)

Mon code ressemble actuellement à ceci:

[AttributeUsage(AttributeTargets.Class)] 
class DisableHtmlEncodeAttribute : DisplayFormatAttribute 
{ 
    public DisableHtmlEncodeAttribute() 
    { 
     HtmlEncode = false; 
    } 
} 

[DisableHtmlEncode] 
internal class InlineImage : IInlineImage 
{ 
    public string AltText { get; set; } 

    public string Src { get; set; } 


    public override string ToString() 
    { 
     return $"<figure><img src=\"{Src}\" alt=\"{AltText}\"></figure>"; 
    } 
} 

Il fonctionne pour l'affichage par défaut, mais quand modèle d'affichage est prévu dans le système de fichiers, il n'est pas utilisé. Probablement parce que quelque chose le coupe en raison de cette annotation de données.

J'ai déjà essayé plusieurs autres approches de ce type:

  • Utilisation première propriété avec l'annotation de données Html
  • Utilisation propriété d'affichage avec l'annotation de données Html
  • mise en œuvre IHtmlString

Mais le cadre semble vérifier les métadonnées seulement pour la classe elle-même, mais pas pour ses propriétés dans ce cas. Et IHtmlString est complètement ignoré.

Je cherche des conseils sur la façon de fournir un modèle d'affichage par défaut pour la classe donnée à partir d'une bibliothèque de classes, qui pourrait être remplacé simplement en plaçant le modèle d'affichage standard dans le dossier des vues.

Répondre

1

Il s'est avéré que j'étais plus proche que je ne le pensais et avec le dernier essai, je l'ai fait fonctionner.

L'astuce est similaire à ce que j'ai fait avec l'attribut DisableHtmlEncode, mais avec l'attribut UIHint. De cette façon, vous pouvez apparemment dire au moteur d'appliquer un modèle d'affichage à une classe, et il est plus fort que l'attribut Format.

Voici le code final qui offre la possibilité pour le balisage HTML par défaut, et quand modèle d'affichage est fourni dans FS, il utilise ce modèle:

[AttributeUsage(AttributeTargets.Class)] 
class DisableHtmlEncodeAttribute : DisplayFormatAttribute 
{ 
    public DisableHtmlEncodeAttribute() 
    { 
     HtmlEncode = false; 
    } 
} 

[AttributeUsage(AttributeTargets.Class)] 
class UseDisplayTemplateAttribute : UIHintAttribute 
{ 
    public UseDisplayTemplateAttribute(string uiHint) 
     : base(uiHint) 
    { 
    } 
} 

[DisableHtmlEncode] 
[UseDisplayTemplate("InlineImage")] 
internal class InlineImage : IInlineImage 
{ 
    public string AltText { get; set; } 

    public string Src { get; set; } 

    public override string ToString() 
    { 
     return $"<figure><img src=\"{Src}\" alt=\"{AltText}\"></figure>"; 
    } 
} 

Je ne suis pas particulièrement fier des hacks, mais ils disent "ce n'est pas stupide si ça marche".

Si quelqu'un a eu une meilleure idée, s'il vous plaît partager ...