MVCを初めて使用し、asp.net Webサイトのチュートリアルを実行しています。
テーブルに表示される長いテキストを切り捨てるカスタムHTMLヘルパーの例が含まれています。
人々がHTMLヘルパーを使用して思いついた他のソリューションと、それらを作成/使用するときに避けるべきベストプラクティスや事柄があるかどうか疑問に思っています。
例として、さまざまな場所に表示する必要がある日付をフォーマットするカスタムヘルパーを作成することを検討していましたが、よりエレガントな解決策がある可能性があることを懸念しています(モデルのDataAnnotations)
何かご意見は?
編集:
私が考えた別の潜在的な用途...文字列の連結。カスタムヘルパーはユーザーIDを入力として受け取り、ユーザーのフルネームを返すことができます...結果は、使用可能なフィールドに応じて、(タイトル)(最初)(中央)(最後)の形式になります。ちょっと考えて、私はまだこのようなことを何も試していません。
DisplayFormat 属性をフォーマットする場合は、いい解決策になるでしょう。
_[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
public DateTime Date { get; set; }
_
そして単に:
_@Html.DisplayFor(x => x.Date)
_
文字列の切り捨てに関する限り、カスタムHTMLヘルパーは良い解決策です。
更新:
EDITに関しては、カスタムHTMLヘルパーがこの状況で機能する可能性がありますが、私が非常に気に入っている別のアプローチとして、ビューモデルがあります。したがって、この特定のビューで常に名前の連結を表示する場合は、ビューモデルを定義できます。
_public class PersonViewModel
{
public string FullName { get; set; }
}
_
これで、コントローラーはリポジトリーを照会してモデルをフェッチし、このモデルをビューにマップしてビューに渡します。これにより、ビューは単に@Html.DisplayFor(x => x.FullName)
になります。モデルとビューモデル間のマッピングは AutoMapper のようなフレームワークで簡略化できます。
私はいつもHtmlHelpersを使用していますが、最も一般的には、気が変わった場合に備えて、ボイラープレートHTMLの生成をカプセル化します。私はそのようなヘルパーを持っていました:
HtmlHelpersの私のお気に入りの用途の1つは、DRY up common form markupです。通常、フォームライン用のコンテナーdiv、ラベル用のdiv、入力用のラベル、検証メッセージ、ヒントテキストなど。最終的に、これは多くのボイラープレートHTMLタグになる可能性があります。これを処理する方法の例を次に示します:
public static MvcHtmlString FormLineDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string labelText = null, string customHelpText = null, object htmlAttributes = null)
{
return FormLine(
helper.LabelFor(expression, labelText).ToString() +
helper.HelpTextFor(expression, customHelpText),
helper.DropDownListFor(expression, selectList, htmlAttributes).ToString() +
helper.ValidationMessageFor(expression));
}
public static MvcHtmlString FormLineEditorFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string templateName = null, string labelText = null, string customHelpText = null, object htmlAttributes = null)
{
return FormLine(
helper.LabelFor(expression, labelText).ToString() +
helper.HelpTextFor(expression, customHelpText),
helper.EditorFor(expression, templateName, htmlAttributes).ToString() +
helper.ValidationMessageFor(expression));
}
private static MvcHtmlString FormLine(string labelContent, string fieldContent, object htmlAttributes = null)
{
var editorLabel = new TagBuilder("div");
editorLabel.AddCssClass("editor-label");
editorLabel.InnerHtml += labelContent;
var editorField = new TagBuilder("div");
editorField.AddCssClass("editor-field");
editorField.InnerHtml += fieldContent;
var container = new TagBuilder("div");
if (htmlAttributes != null)
container.MergeAttributes(new RouteValueDictionary(htmlAttributes));
container.AddCssClass("form-line");
container.InnerHtml += editorLabel;
container.InnerHtml += editorField;
return MvcHtmlString.Create(container.ToString());
}
public static MvcHtmlString HelpTextFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string customText = null)
{
// Can do all sorts of things here -- eg: reflect over attributes and add hints, etc...
}
ただし、これを実行すると、次のようなフォーム行を出力できます。
<%: Html.FormLineEditorFor(model => model.Property1) %>
<%: Html.FormLineEditorFor(model => model.Property2) %>
<%: Html.FormLineEditorFor(model => model.Property3) %>
...そしてBAM、すべてのラベル、入力、ヒント、および検証メッセージがページにあります。繰り返しますが、モデルの属性を使用し、それらを反映して、本当にスマートでドライなものにすることができます。もちろん、フォームデザインで標準化できない場合、これは時間の無駄になります。ただし、cssが必要なすべてのカスタマイズを提供できる単純なケースでは、grrrrrrrrreatで動作します!
ストーリーのモラル-HtmlHelpersは、ハンドメイドのマークアップをビューごとに破壊するグローバルなデザイン変更からユーザーを隔離できます。私は彼らが好き。しかし、やり過ぎることもあり、時には部分的なビューはコード化されたヘルパーよりも優れています。 ヘルパーと部分ビューのどちらを使用するかを決定するために使用する一般的な経験則:HTMLのチャンクに多くの条件付きロジックまたはコーディングのトリックが必要な場合は、ヘルパーを使用します(コードにコードを配置する必要があります)ある);そうでない場合、あまりロジックなしで一般的なマークアップを出力するだけの場合は、部分ビューを使用します(マークアップを配置する場所にマークアップを配置します)。
これがあなたにいくつかのアイデアを与えることを願っています!
public static HtmlString OwnControlName<T, U>(this HtmlHelper<T> helper, Expression<Func<T, U>> expression, string label_Name = "", string label_Title = "", Attr attr = null)
{
TemplateBuilder tb = null;
string template = null;
if (expression == null) throw new ArgumentException("expression");
obj = helper.ViewData.Model;
tb.Build(obj, expression.Body as MemberExpression, typeof(T), new SimpleTemplate(new TextArea()), label_Name, label_Title, attr);
template = tb.Get();
return new MvcHtmlString(template);
}