ASP.NET MVCレッスン8.ビュー、カミソリ、エラーページ

レッスンの目的 。 Razorを使用して、htmlでデータを描画する方法を学びます。 ヘルパー。 PageableData 動的フォーム。 RedirectToLogin、RedirectToNotFoundPage。 エラーページ。 RssActionResult。



ベース


それでは、ビューの一部がどのように機能するかを見てみましょう。

コントローラーでは、すべてのアクションメソッドがActionResult型を返します。 結果を表示するには、次を使用します。

return View(modelData);









ビューの主なパラメーターは次のとおりです。





使用するビューの選択は次のとおりです。



勉強を始めましょう。



かみそり


ビューを作成する場合、ASPXとRazorの2つのエンジンから選択できます。 将来的には最初のものを使用しないので、Razorについて話しましょう。







ASPXは、コード実行用の<% %>



%% <% %>



タグとデータ出力用の<%: %>



を持つ面倒なエンジンでした。



Razorは@Model.Name



使用します。 つまり @



で始まるものはすべて、コード実行またはデータ出力@foreach() {…}



、または@if() { … } else { … }



ます。



 @if (Model.Any()) { <p></p> } @foreach (var role in Model) { <div class="item"> <span class="id"> @role.ID </span> <span class="name"> @role.Name </span> <span class="Code"> @role.Code </span> </div> }
      
      







{}内にはタグがあります-これは、これがテンプレートであることのマーカーです。 テンプレート内でコードを簡単に実行するには、@ {code}構造を使用します;属性またはテキスト内のデータを正しく出力するには、構造は@(文字列結果)です。

 @{ int i = 0; } @foreach (var role in Model) { <div class="item @(i % 2 == 0 ? "odd" : "")"> <span class="id"> @role.ID </span> <span class="name"> @role.Name </span> <span class="Code"> @role.Code </span> </div> i++; }
      
      





タグなしのテキストを表示するには、擬似タグを使用する必要があります。

 @foreach (var role in Model) { @role.Name<text>, </text> }
      
      





htmlテキストを出力するには、MvcHtmlStringを返すか、 Html .Raw(html-string-value)コンストラクトを使用する必要があります。そうでない場合、テキストはエスケープタグで表示されます。



PageableData


データベースからのテーブルのページ出力を考えてみましょう。 分析しましょう:

  1. コントローラーは、出力するページの値をパラメーターで受け取る必要があります
  2. デフォルトでは、これが最初のページになります。
  3. 結論として、次のことを知っておく必要があります。

    1. 表示するデータベースアイテムのリスト
    2. ページ数
    3. 現在のページ




ジェネリッククラスPageableData(/Models/Info/PageableData.cs)を作成します。

 public class PageableData<T> where T : class { protected static int ItemPerPageDefault = 20; public IEnumerable<T> List { get; set; } public int PageNo { get; set; } public int CountPage { get; set; } public int ItemPerPage { get; set; } public PageableData(IQueryable<T> queryableSet, int page, int itemPerPage = 0) { if (itemPerPage == 0) { itemPerPage = ItemPerPageDefault; } ItemPerPage = itemPerPage; PageNo = page; var count = queryableSet.Count(); CountPage = (int)decimal.Remainder(count, itemPerPage) == 0 ? count / itemPerPage : count / itemPerPage + 1; List = queryableSet.Skip((PageNo - 1) * itemPerPage).Take(itemPerPage); } }
      
      







デフォルトでは、ページごとに表示される値の数は20ですが、コンストラクターでこのパラメーターを変更できます。 IQueryableを渡し、CountPageのページ数を計算します。 PageNoを使用して、ページを選択します。

 List = queryableSet.Skip((PageNo - 1) * itemPerPage).Take(itemPerPage);
      
      







コントローラーでは次を使用します。

 public class UserController : DefaultController { public ActionResult Index(int page = 1) { var data = new PageableData<User>(Repository.Users, page, 30); return View(data); } …
      
      





Viewでは、このクラスを使用します。

 @model LessonProject.Models.Info.PageableData<LessonProject.Model.User> @{ ViewBag.Title = "Users"; Layout = "~/Areas/Default/Views/Shared/_Layout.cshtml"; } <h2>Users</h2> <p> @foreach (var user in Model.List) { <div class="item"> <span class="id"> @user.ID </span> <span class="email"> @user.Email </span> <span class="activateDate"> @user.AddedDate </span> </div> } </p>
      
      





実行、確認(http:// localhost / User)







続行するには、より多くのデータを生成します(サーバーエクスプローラーのテーブルでctrl-c、ctrl-vのみ)







ヘルパーページの作成に移りましょう。これにより、このリストをスクロールできます。



ヘルパー(PagerHelper)


ブートストラップを使用するため、それに基づいてページネーターも作成します。 コードでは、次のようになります。



 <div class="pagination"> <ul> <li><a href="#">Prev</a></li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li><a href="#">Next</a></li> </ul> </div>
      
      







私たちは内部にのみ興味があります。

ヘルパーは、System.Web.Mvc.HtmlHelperクラスの拡張機能として作成されます。 計画は次のとおりです。



コードは次のようになります。

 public static MvcHtmlString PageLinks(this HtmlHelper html, int currentPage, int totalPages, Func<int, string> pageUrl) { StringBuilder builder = new StringBuilder(); //Prev var prevBuilder = new TagBuilder("a"); prevBuilder.InnerHtml = "«"; if (currentPage == 1) { prevBuilder.MergeAttribute("href", "#"); builder.AppendLine("<li class=\"active\">" + prevBuilder.ToString() + "</li>"); } else { prevBuilder.MergeAttribute("href", pageUrl.Invoke(currentPage - 1)); builder.AppendLine("<li>" + prevBuilder.ToString() + "</li>"); } //  for (int i = 1; i <= totalPages; i++) { //      if (((i <= 3) || (i > (totalPages - 3))) || ((i > (currentPage - 2)) && (i < (currentPage + 2)))) { var subBuilder = new TagBuilder("a"); subBuilder.InnerHtml = i.ToString(CultureInfo.InvariantCulture); if (i == currentPage) { subBuilder.MergeAttribute("href", "#"); builder.AppendLine("<li class=\"active\">" + subBuilder.ToString() + "</li>"); } else { subBuilder.MergeAttribute("href", pageUrl.Invoke(i)); builder.AppendLine("<li>" + subBuilder.ToString() + "</li>"); } } else if ((i == 4) && (currentPage > 5)) { //  builder.AppendLine("<li class=\"disabled\"> <a href=\"#\">...</a> </li>"); } else if ((i == (totalPages - 3)) && (currentPage < (totalPages - 4))) { //  builder.AppendLine("<li class=\"disabled\"> <a href=\"#\">...</a> </li>"); } } //Next var nextBuilder = new TagBuilder("a"); nextBuilder.InnerHtml = "»"; if (currentPage == totalPages) { nextBuilder.MergeAttribute("href", "#"); builder.AppendLine("<li class=\"active\">" + nextBuilder.ToString() + "</li>"); } else { nextBuilder.MergeAttribute("href", pageUrl.Invoke(currentPage + 1)); builder.AppendLine("<li>" + nextBuilder.ToString() + "</li>"); } return new MvcHtmlString("<ul>" + builder.ToString() + "</ul>"); }
      
      







ビュー内の宣言に名前空間LessonProject.Helperを追加します。 これを行うには2つの方法があります。





ビューにページネーターを追加します。

  <div class="pagination"> @Html.PageLinks(Model.PageNo, Model.CountPage, x => Url.Action("Index", new {page = x})) </div>
      
      







設計に注意を払う

x => Url.Action("Index", new {page = x})





これは、ページへのリンクを返すデリゲートです。 そしてUrl.Action()-パラメータpage = xでページ/ユーザー/インデックスへのリンクを形成します。

発生した内容は次のとおりです(ページあたりの出力量を5に減らして、より多くのページが形成されるようにしました)







SearchEngine


データを表示する次のステップは、検索を作成することです。 検索は、データフィールドの1つのサブストリングが一致することにより、簡単になります。 入力パラメーターはsearchStringです。

 public ActionResult Index(int page = 1, string searchString = null) { if (!string.IsNullOrWhiteSpace(searchString)) { //  return View(data); } else { var data = new PageableData<User>(Repository.Users, page, 5); return View(data); } }
      
      







値を取るクラスSearchEngine



を作成します
  IQueryable,   ,      (/Global/SearchEngine.cs): 
      

, , [,], {,}, (,):

/// <summary> /// The regex strip html. /// </summary> private static readonly Regex RegexStripHtml = new Regex("<[^>]*>", RegexOptions.Compiled); private static string StripHtml(string html) { return string.IsNullOrWhiteSpace(html) ? string.Empty : RegexStripHtml.Replace(html, string.Empty).Trim(); } private static string CleanContent(string content, bool removeHtml) { if (removeHtml) { content = StripHtml(content); } content = content.Replace("\\", string.Empty). Replace("|", string.Empty). Replace("(", string.Empty). Replace(")", string.Empty). Replace("[", string.Empty). Replace("]", string.Empty). Replace("*", string.Empty). Replace("?", string.Empty). Replace("}", string.Empty). Replace("{", string.Empty). Replace("^", string.Empty). Replace("+", string.Empty); var words = content.Split(new[] { ' ', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); var sb = new StringBuilder(); foreach (var word in words.Select(t => t.ToLowerInvariant().Trim()).Where(word => word.Length > 1)) { sb.AppendFormat("{0} ", word); } return sb.ToString(); }








:

public static IEnumerable<User> Search(string searchString, IQueryable<User> source) { var term = CleanContent(searchString.ToLowerInvariant().Trim(), false); var terms = term.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var regex = string.Format(CultureInfo.InvariantCulture, "({0})", string.Join("|", terms)); foreach (var entry in source) { var rank = 0; if (!string.IsNullOrWhiteSpace(entry.Email)) { rank += Regex.Matches(entry.Email.ToLowerInvariant(), regex).Count; } if (rank > 0) { yield return entry; } } }







. regex . , Email .



:

, , «cher [2]», , «cher 2». regex = (cher|2). , IQueryable





, IEnumerable - yield return entry





IQueryable, , (/Global/SearchEngine.cs):

, , [,], {,}, (,):

/// <summary> /// The regex strip html. /// </summary> private static readonly Regex RegexStripHtml = new Regex("<[^>]*>", RegexOptions.Compiled); private static string StripHtml(string html) { return string.IsNullOrWhiteSpace(html) ? string.Empty : RegexStripHtml.Replace(html, string.Empty).Trim(); } private static string CleanContent(string content, bool removeHtml) { if (removeHtml) { content = StripHtml(content); } content = content.Replace("\\", string.Empty). Replace("|", string.Empty). Replace("(", string.Empty). Replace(")", string.Empty). Replace("[", string.Empty). Replace("]", string.Empty). Replace("*", string.Empty). Replace("?", string.Empty). Replace("}", string.Empty). Replace("{", string.Empty). Replace("^", string.Empty). Replace("+", string.Empty); var words = content.Split(new[] { ' ', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); var sb = new StringBuilder(); foreach (var word in words.Select(t => t.ToLowerInvariant().Trim()).Where(word => word.Length > 1)) { sb.AppendFormat("{0} ", word); } return sb.ToString(); }








:

public static IEnumerable<User> Search(string searchString, IQueryable<User> source) { var term = CleanContent(searchString.ToLowerInvariant().Trim(), false); var terms = term.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var regex = string.Format(CultureInfo.InvariantCulture, "({0})", string.Join("|", terms)); foreach (var entry in source) { var rank = 0; if (!string.IsNullOrWhiteSpace(entry.Email)) { rank += Regex.Matches(entry.Email.ToLowerInvariant(), regex).Count; } if (rank > 0) { yield return entry; } } }







. regex . , Email .



:

, , «cher [2]», , «cher 2». regex = (cher|2). , IQueryable





, IEnumerable - yield return entry





  IQueryable,   ,      (/Global/SearchEngine.cs): 
      

, , [,], {,}, (,):

/// <summary> /// The regex strip html. /// </summary> private static readonly Regex RegexStripHtml = new Regex("<[^>]*>", RegexOptions.Compiled); private static string StripHtml(string html) { return string.IsNullOrWhiteSpace(html) ? string.Empty : RegexStripHtml.Replace(html, string.Empty).Trim(); } private static string CleanContent(string content, bool removeHtml) { if (removeHtml) { content = StripHtml(content); } content = content.Replace("\\", string.Empty). Replace("|", string.Empty). Replace("(", string.Empty). Replace(")", string.Empty). Replace("[", string.Empty). Replace("]", string.Empty). Replace("*", string.Empty). Replace("?", string.Empty). Replace("}", string.Empty). Replace("{", string.Empty). Replace("^", string.Empty). Replace("+", string.Empty); var words = content.Split(new[] { ' ', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); var sb = new StringBuilder(); foreach (var word in words.Select(t => t.ToLowerInvariant().Trim()).Where(word => word.Length > 1)) { sb.AppendFormat("{0} ", word); } return sb.ToString(); }








:

public static IEnumerable<User> Search(string searchString, IQueryable<User> source) { var term = CleanContent(searchString.ToLowerInvariant().Trim(), false); var terms = term.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var regex = string.Format(CultureInfo.InvariantCulture, "({0})", string.Join("|", terms)); foreach (var entry in source) { var rank = 0; if (!string.IsNullOrWhiteSpace(entry.Email)) { rank += Regex.Matches(entry.Email.ToLowerInvariant(), regex).Count; } if (rank > 0) { yield return entry; } } }







. regex . , Email .



:

, , «cher [2]», , «cher 2». regex = (cher|2). , IQueryable





, IEnumerable - yield return entry





IQueryable, , (/Global/SearchEngine.cs):

, , [,], {,}, (,):

/// <summary> /// The regex strip html. /// </summary> private static readonly Regex RegexStripHtml = new Regex("<[^>]*>", RegexOptions.Compiled); private static string StripHtml(string html) { return string.IsNullOrWhiteSpace(html) ? string.Empty : RegexStripHtml.Replace(html, string.Empty).Trim(); } private static string CleanContent(string content, bool removeHtml) { if (removeHtml) { content = StripHtml(content); } content = content.Replace("\\", string.Empty). Replace("|", string.Empty). Replace("(", string.Empty). Replace(")", string.Empty). Replace("[", string.Empty). Replace("]", string.Empty). Replace("*", string.Empty). Replace("?", string.Empty). Replace("}", string.Empty). Replace("{", string.Empty). Replace("^", string.Empty). Replace("+", string.Empty); var words = content.Split(new[] { ' ', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); var sb = new StringBuilder(); foreach (var word in words.Select(t => t.ToLowerInvariant().Trim()).Where(word => word.Length > 1)) { sb.AppendFormat("{0} ", word); } return sb.ToString(); }








:

public static IEnumerable<User> Search(string searchString, IQueryable<User> source) { var term = CleanContent(searchString.ToLowerInvariant().Trim(), false); var terms = term.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var regex = string.Format(CultureInfo.InvariantCulture, "({0})", string.Join("|", terms)); foreach (var entry in source) { var rank = 0; if (!string.IsNullOrWhiteSpace(entry.Email)) { rank += Regex.Matches(entry.Email.ToLowerInvariant(), regex).Count; } if (rank > 0) { yield return entry; } } }







. regex . , Email .



:

, , «cher [2]», , «cher 2». regex = (cher|2). , IQueryable





, IEnumerable - yield return entry








All Articles