MVC6 introduit Tag Helpers qui est un meilleur moyen que d’utiliser @ Html.EditorFor, etc. Cependant, je n’ai trouvé aucun Tag Helper qui soit une alternative à @ Html.DisplayFor.
Bien sûr, je peux utiliser une variable directement sur une page Razor, telle que @ Model.BookingCode. Mais cela ne permet pas de contrôler le formatage.
Avec MVC6, quelle est la méthode conceptuelle correcte pour afficher une valeur d'une propriété de modèle?
Vous pouvez créer votre propre assistant de tag
namespace MyDemo.TagHelpers
{
[HtmlTargetElement("p", Attributes = ForAttributeName)]
public class DisplayForTagHelper : TagHelper
{
private const string ForAttributeName = "asp-for";
[HtmlAttributeName(ForAttributeName)]
public ModelExpression For { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
var text = For.ModelExplorer.GetSimpleDisplayText();
output.Content.SetContent(text);
}
}
}
Ajouter l'utiliser en vue:
<p asp-for="MyProperty" class="form-control-static"></p>
@ Html.DisplayFor existe toujours et peut toujours être utilisé.
La différence entre HtmlHelpers et TagHelpers réside dans le fait que HtmlHelpers choisit les éléments html à restituer pour vous, tandis que les utilitaires TagHelpers fonctionnent avec les balises html que vous ajoutez vous-même, ce qui vous donne un contrôle plus complet sur l'élément html utilisé. Vous avez un certain contrôle sur le balisage à l'aide de modèles avec HtmlHelpers mais vous avez plus de contrôle avec TagHelpers.
Vous devez donc penser en termes de balisage HTML que je souhaite insérer dans cette propriété de modèle et l'ajouter autour de la propriété elle-même à l'aide de @ Model.Property avec un balisage ou continuer à utiliser DisplayFor si vous préférez laisser l'assistant décider.
try below code
public class movie
{
public int ID { get; set; }
[DisplayName("Movie Title")]
public string Title { get; set; }
}
///////////////////////////////////////////////////
@model IEnumerable<MvcMovie.Models.Movie>
<h1>Show List Movies</h1>
<label asp-for="ToList()[0].Title">< /label>
@foreach (var movie in Model)
{
@movie.Title
}
Je l'utilise comme assistant d'affichage.
[HtmlTargetElement("*", Attributes = ForAttributeName)]
public class DisplayForTagHelper : TagHelper
{
private const string ForAttributeName = "asp-display-for";
private readonly IHtmlHelper _html;
public DisplayForTagHelper(IHtmlHelper html)
{
_html = html;
}
[HtmlAttributeName(ForAttributeName)]
public ModelExpression Expression { get; set; }
public IHtmlHelper Html
{
get
{
(_html as IViewContextAware)?.Contextualize(ViewContext);
return _html;
}
}
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
if (output == null)
throw new ArgumentNullException(nameof(output));
var type = Expression.Metadata.UnderlyingOrModelType;
if (type.IsPrimitive)
{
output.Content.SetContent(Expression.ModelExplorer.GetSimpleDisplayText());
}
// Special Case for Personal Use
else if (typeof(Dictionary<string, string>).IsAssignableFrom(type))
{
output.Content.SetHtmlContent(Html?.Partial("Dictionary", Expression.ModelExplorer.Model));
}
else
{
var htmlContent = Html.GetHtmlContent(Expression);
output.Content.SetHtmlContent(htmlContent);
}
}
}
public static class ModelExpressionExtensions
{
public static IHtmlContent GetHtmlContent(this IHtmlHelper html, ModelExpression expression)
{
var ViewEngine = html.ViewContext.HttpContext.RequestServices.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine;
var BufferScope = html.GetFieldValue<IViewBufferScope>();
var htmlContent = new TemplateBuilder(ViewEngine, BufferScope, html.ViewContext, html.ViewContext.ViewData, expression.ModelExplorer, expression.Name, null, true, null).Build();
return htmlContent;
}
public static TValue GetFieldValue<TValue>(this object instance)
{
var type = instance.GetType();
var field = type.GetFields(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).FirstOrDefault(e => typeof(TValue).IsAssignableFrom(e.FieldType));
return (TValue)field?.GetValue(instance);
}
}