ASP.NET MVC-カスタムHtmlHelperメソッド

16292 ワード

HtmlHelperメソッドはASP.NET MVCの中でも非常に強力な特性で、この特性があれば、私たちはもっと好きなように自分のページをカスタマイズすることができます.
独自のHtmlHelperメソッドをカスタマイズするには、次の3つの方法があります.
一.Razor構文
Razorを採用する方法は非常に直感的で、このようにしています.
@model IEnumerable<MusicShop.Models.Album>
@{
    ViewBag.Title = "Index";
}

@helper Truncate(string input, int length)
{
    if (input.Length <= length)
    {
       @input;
    }
    else
    {
       @input.Substring(0, length)<text>...</text>;
    }
}

<h2>Index</h2>
<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            Genre
        </th>
        <th>
            Artist
        </th>
        <th>
            Title
        </th>
        <th>
            Price
        </th>
        <th>
            AlbumArtUrl
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Genre.Name)
        </td>
        <td>
            @Truncate(item.Artist.Name, 25);
        </td>
        <td>
             @Truncate(item.Title, 25);
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.AlbumArtUrl)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.AlbumId }) |
            @Html.ActionLink("Details", "Details", new { id=item.AlbumId }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.AlbumId })
        </td>
    </tr>
}

</table>

@helperはコンパイラにヒントを与えます.これは補助方法です.私たちは@+MethodNameの方法でこの補助方法を使用することができます.もちろん、Webプログラミングでは、インラインは、ページのロードが遅くなり、特にページの繰り返しロードが遅くなるため、よくありません.より一般的な方法は、名前空間で補助メソッドを定義し、ページに補助メソッドを導入することで、メソッドのソースコードのロードの負担を負う必要がなくなります.
二.拡張メソッド
このような方法では、通常、カスタムのアシストメソッドを格納するフォルダを新規作成する必要があります(多くの場合、カスタムのアシストメソッドは多いかもしれませんが、Controller、Modelsのようなフォルダはこれらのメソッドを格納するのに適していません)、実際には、アシストメソッドのために新しいネーミングスペースを構築する必要があります.
このように:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;


namespace MusicShop.Helpers
{
    public static class HtmlHelpers
    {
        public static string Truncate(this HtmlHelper helper, string input, int length) 
        { 
            if (input.Length <= length) 
            { 
                return input; 
            } 
            else 
            { 
                return input.Substring(0, length) + "..."; 
            }
        } 
    }
}

次に、ページに次のコードを追加します.
@model IEnumerable<MusicShop.Models.Album>
@{
    ViewBag.Title = "Index";
}

@using MusicShop.Helpers

<h2>Index</h2>
<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            Genre
        </th>
        <th>
            Artist
        </th>
        <th>
            Title
        </th>
        <th>
            Price
        </th>
        <th>
            AlbumArtUrl
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Genre.Name)
        </td>
        <td>
            @Html.Truncate(item.Artist.Name, 25);
        </td>
        <td>
             @Html.Truncate(item.Title, 25);
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.AlbumArtUrl)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.AlbumId }) |
            @Html.ActionLink("Details", "Details", new { id=item.AlbumId }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.AlbumId })
        </td>
    </tr>
}

</table>

@usingは必須で、アシストメソッドが存在するネーミングスペースを導入します.補助法の処理についてはHtmlHelperの拡張法として用いていることが分かる.拡張手法の使用により,本来非常に複雑なMVC設計でも良好な可読性が得られ,柔軟性と多重性が非常に高い.私がC#を学んだばかりの頃、拡張方法に特に風邪を引いたことはありませんでした.その使用は拡張タイプのネーミングスペースを「汚染」しやすいので、私たちはこのタイプの方法を探すときにとてもうんざりしていました.しかしMVCを使う時、特にHtmlHelper方法の時、拡張方法は私にとても大きいショックを与えました:拡張方法がなければ、全体のコードの可読性は本当に恐ろしいです!この時私はC#の設計理念を思い出しました:コードを読んで書きます.はい、拡張方法を使用すると、私たちのコードは完全な文のように他の人に読まれ、ある困難な場所で止まることはありません.
もちろん、文法糖を乱用するのは危険な行為です.結局、拡張方法には私がさっき言った欠点があります.特にソフトウェアの後続の発展を考えると、私たちは冷や汗をかきます.将来、あるタイプに私の拡張方法と同じ方法を追加すると、私のコードが間違ってしまいます.
だから、私たちはもっと安全な方法が必要です.
三.Razor view
次のようにcshtmlを新規作成できます.
@helper TruncateString(string input, int length)
{
    if (input.Length <= length) {
        @input
    } else {
        @input.Substring(0, length)<text>...</text>
    }
}

次のページがあります.
@model IEnumerable<MusicShop.Models.Album>
@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>
<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            Genre
        </th>
        <th>
            Artist
        </th>
        <th>
            Title
        </th>
        <th>
            Price
        </th>
        <th>
            AlbumArtUrl
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Genre.Name)
        </td>
        <td>
            @Helpers.Truncate(item.Artist.Name, 25);
        </td>
        <td>
             @Helpers.Truncate(item.Title, 25);
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.AlbumArtUrl)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.AlbumId }) |
            @Html.ActionLink("Details", "Details", new { id=item.AlbumId }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.AlbumId })
        </td>
    </tr>
}

</table>

この方法を使用すると、Razor構文のインラインも拡張方法の後顧の憂いもなく、新しいカスタムメソッドを自由に追加することができますが、注意してください.Helpers.cshtmlはApp_に置く必要があります.コードの中.