问题
I recently started my first project using Razor Pages, I am using EF Core and have scaffolded all of my models into CRUD Razor Pages. Something I noticed was that the Create and Edit Razor Pages that are generated use Tag Helpers to display the data. i.e.
<div class="form-group">
<label asp-for="ViewModel.Name" class="control-label"></label>
<input asp-for="ViewModel.Name" class="form-control" />
<span asp-validation-for="ViewModel.Name" class="text-danger"></span>
</div>
Whereas the Index, Details, and Delete Pages use Html Helpers to display the data. i.e.
<dt>
@Html.DisplayNameFor(model => model.ViewModel.Name)
</dt>
<dd>
@Html.DisplayFor(model => model.ViewModel.Name)
</dd>
This link from Microsoft says that "Tag Helpers reduce the explicit transitions between HTML and C# in Razor views. In many cases, HTML Helpers provide an alternative approach to a specific Tag Helper, but it's important to recognize that Tag Helpers don't replace HTML Helpers and there's not a Tag Helper for each HTML Helper.".
But certainly these basic display fields could be displayed with Tag Helpers. This seems to me like a rather frivolous inconsistency and I would think that it would be better practice to use Tag Helpers primarily and Html Helpers only when absolutely neccecary.
I assume that the developers had a reason for doing it this way, but what that might be escapes me. Could anyone please shine some light on this for me please?
回答1:
Simple: there's no tag helpers for display.
Expanded:
Having tag helpers for things like inputs makes sense: there's specific HTML tags associated with that. Things get a lot more blurry with display. Each individual developer might want to use different tags for display: span
, strong
, th
, dt
, etc. There's no one-size fits all here. You might not even want a tag at all. By default Html.DisplayFor
and Html.DisplayNameFor
just output the values, without any tags.
Also, these are templated helpers, which means you as a developer can actually add templates to Views\Shared\DisplayTemplates
and customize how things are displayed. For example, you could at a String.cshtml
view there, with something like:
@model string
<strong>@Model</strong>
And now, any string property displayed using Html.DisplayFor
would be wrapped in strong
tags. This level of customization wouldn't be possible with tag helpers.
EDIT
FWIW, if you really want to use tag helpers, you can just add your own. For example:
public class DisplayNameTagHelper : TagHelper
{
public ModelExpression For { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "strong";
output.Content.SetContent(For.Metadata.DisplayName);
}
}
Then in your view:
<display-name for="MyProperty" />
Writing a DisplayTagHelper
would be similar in concept, but a bit more difficult. You can get the value from For.Model
. However, this is typed as object
. Using information available on For.Metadata
, you'd need to determine what you're actually working with and probably have a few different branches to display things differently depending on the type. There's also For.Metadata.DataFormatString
that would need to be taken into account with things like decimals, DateTimes, etc.
来源:https://stackoverflow.com/questions/57825275/why-does-razor-pages-scaffolding-use-html-helpers-and-not-tag-helpers-for-inde