Razor Page入門 - 9

by vivid 30. 九月 2020 12:05

.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號:N200922203
出刊日期: 2020/9/30

這篇文章將延續《Razor Page入門 - 8》一文的情境,介紹如何在ASP.NET Razor Page網站專案加入資料篩選條件,以瞭解如何設計資料搜尋功能。我們希望在表單之中使用文字方塊接收使用者輸入的篩選條件,並使用HTTP Get將查詢關鍵字傳送到伺服端的Razor Page,在其中撰寫資料存取邏輯,將滿足條件的資料回傳以在Razor Page中呈現。

定義服務

修改「MyServices」服務專案「IBookRepository」介面的程式碼,在「IBookRepository」介面之中,新增一個「GetBookByKeyword」方法,這個方法將根據傳入的「keyword」參數的值,來篩選出圖書名稱包含此字串的圖書資料,同時,這個方法將會回傳「IEnumerable<Book>」物件,包含所有滿足篩選條件的圖書物件,參考以下範例程式碼:

MyServices\IBookRepository.cs

using MyModels;
using System;
using System.Collections.Generic;
using System.Text;

namespace MyServices {
  public interface IBookRepository {
    IEnumerable<Book> GetAllBooks();
    Book GetBook( int id );
    Book Update( Book editBook );
    Book Create( Book newBook );
    Book Delete( int id );
    IEnumerable<CategoryCount> GetBookCountByCategory( );
    IEnumerable<Book> GetBookByKeyword( string keyword );
  }
}


實作服務

接著我們在「MyServices」服務專案「BookRepository」類別中,實作「IBookRepository」介面的「GetBookByKeyword」方法,查詢出滿足篩選條件的圖書資料,請參考以下程式碼:

MyServices\BookRepository.cs

using MyModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyServices {
  public class BookRepository : IBookRepository {
    private List<Book> _books = null;
    public BookRepository( ) {
      _books = new List<Book>() {
         new Book() {
           Id = 1 ,
           Title = " Essential Programming Language " ,
           Price = 250 ,
           PublishDate = new DateTime( 2019 ,1,2 ) ,
           InStock = true ,
           Description = "Essential Programming Language "  ,
          Category = Category.Computers
         },
         new Book() {
           Id = 2 ,
           Title = "Telling Arts" ,
           Price = 245 ,
           PublishDate = new DateTime( 2019 , 4 , 15 ) ,
           InStock = true ,
           Description = " Telling Arts "  ,
          Category = Category.Arts
         },
           new Book() {
           Id = 3 ,
           Title = "Marvel" ,
           Price = 150  ,
           PublishDate = new DateTime( 2019 , 2, 21 ) ,
           InStock = true ,
           Description = " Marvel "  ,
          Category = Category.Commics
         },
          new Book() {
           Id = 4 ,
           Title = "The Beauty of Cook" ,
           Price = 450 ,
           PublishDate = new DateTime( 2019 ,12, 2 ) ,
           InStock = true ,
           Description = " The Beauty of Cook "  ,
           Category = Category.Cooking
         },
          new Book() {
           Id = 5 ,
           Title = " Learning how to Cook " ,
           Price = 450 ,
           PublishDate = new DateTime( 2020 , 1, 20 ) ,
           InStock = true ,
           Description = " Learning how to Cook  "  ,
           Category = Category.Cooking
         }
      };
    }

    public Book Delete( int id ) {
      Book book = _books.FirstOrDefault( b => b.Id == id );
      if ( book != null ) {
        _books.Remove( book );
      }
      return book;
    }
    public Book Create( Book newBook ) {
      newBook.Id = _books.Max( b => b.Id ) + 1;
      _books.Add( newBook );
      return newBook;
    }

 

 

    public Book GetBook( int id ) {
      return _books.FirstOrDefault( b => b.Id == id );
    }

    public Book Update( Book editBook ) {
      Book book = _books.FirstOrDefault( b => b.Id == editBook.Id );
      if ( book != null ) {
        book.Title = editBook.Title;
        book.Price = editBook.Price;
        book.PublishDate = editBook.PublishDate;
        book.InStock = editBook.InStock;
        book.Description = editBook.Description;
        book.Category = editBook.Category;
      }
      return book;
    }

    public IEnumerable<CategoryCount> GetBookCountByCategory( ) {
      return _books
        .GroupBy( b => b.Category )
        .Select( g => new CategoryCount() {
          Category = g.Key.Value,
          Count = g.Count()
        } ).ToList();

    }
    public IEnumerable<Book> GetAllBooks( ) {
      return _books;
    }
    public IEnumerable<Book> GetBookByKeyword( string keyword ) {
      return _books
              .Where( b => b.Title.Contains( keyword ) )
              .ToList();
    }
  }
}

 

設計Razor Page

我們希望能夠送出HTTP Get請求,並將查詢關鍵字傳送到Razor Page,使用HTTP Get的好處是能讓使用者連同輸入的查詢關鍵字加到我的最愛,不用每次都手動輸入篩選條件。修改「Books\List.cshtml」檔案程式碼,加入<form>標籤,在其中使用<Input>標記協助程式(Tag Helper)加入一個文字方塊,標計參考以下範例程式碼:

MyRazorWeb\Pages\Books\List.cshtml

@page
@model MyRazorWeb.ListModel
@{
  ViewData[ "Title" ] = "List";
}

<h1> List </h1>


<form class = "form-inline" method = "get">
  <label class = "sr-only" for = "Keyword"> Keyword : </label>
  <input class = "form-control mb-2 mr-sm-2" asp-for = "Keyword"  placeholder = "Input Search keyword">
  <button type = "submit" class = "btn btn-primary mb-2"> Search </button>
</form>

<table class = "table">
  <thead>
    <tr>
      <th>
        @Html.DisplayNameFor( model => ( (IList<MyModels.Book>) model.Books )[ 0 ].Id )
      </th>
      <th>
        @Html.DisplayNameFor( model => ( (IList<MyModels.Book>) model.Books )[ 0 ].Title )
      </th>
      <th>
        @Html.DisplayNameFor( model => ( (IList<MyModels.Book>) model.Books )[ 0 ].Price )
      </th>
      <th>
        @Html.DisplayNameFor( model => ( (IList<MyModels.Book>) model.Books )[ 0 ].PublishDate )
      </th>
      <th>
        @Html.DisplayNameFor( model => ( (IList<MyModels.Book>) model.Books )[ 0 ].InStock )
      </th>
      <th>
        @Html.DisplayNameFor( model => ( (IList<MyModels.Book>) model.Books )[ 0 ].Description )
      </th>
      <th>
        @Html.DisplayNameFor( model => ( (IList<MyModels.Book>) model.Books )[ 0 ].Category )
      </th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    @foreach ( var item in Model.Books ) {
      <tr>
        <td>
          @Html.DisplayFor( modelItem => item.Id )
        </td>
        <td>
          @Html.DisplayFor( modelItem => item.Title )
        </td>
        <td>
          @Html.DisplayFor( modelItem => item.Price )
        </td>
        <td>
          @Html.DisplayFor( modelItem => item.PublishDate )
        </td>
        <td>
          @Html.DisplayFor( modelItem => item.InStock )
        </td>
        <td>
          @Html.DisplayFor( modelItem => item.Description )
        </td>
        <td>
          @Html.DisplayFor( modelItem => item.Category )
        </td>
        <td>
          <a asp-page = "./Details" asp-route-Id = "@item.Id"> Details </a> |
          <a asp-page = "./Edit" asp-route-Id = "@item.Id"> Edit </a> |
          <a asp-page = "./Delete" asp-route-Id = "@item.Id"> Delete </a>
        </td>
      </tr>
    }
  </tbody>
</table>
<hr />
<vc:category-summary vc-title = "Book Category Count Summary"> </vc:category-summary>

 

修改「Books\List.cshtml.cs」檔案程式碼,參考以下範例程式碼,加入一個「Keyword」屬性,這個屬性的名稱和<form>標籤中輸入查詢關鍵字的文字方塊名稱相同,套用了 [ BindProperty ( SupportsGet = true ) ] 之後,ASP.NET Razor Page會自動將文字方塊輸入的值繫結到這個「Keyword」屬性中。預設繫結的動作只有在HTTP Post請求時才會發生,因此我們將「SupportsGet」設定為「true」,以便從查詢字串中將查詢關鍵字的值傳到「Keyword」屬性中。

MyRazorWeb\Pages\Books\List.cshtml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using MyModels;
using MyServices;
namespace MyRazorWeb {
  public class ListModel : PageModel {
    private readonly IBookRepository _bookRepository;
    public IEnumerable<Book> Books { get; set; }

    [BindProperty( SupportsGet = true )]
    public string Keyword { get; set; }

    public ListModel( IBookRepository bookRepository ) {
      _bookRepository = bookRepository;
    }

    public void OnGet( ) {
      if ( Keyword != null ) {
        Books = this._bookRepository.GetBookByKeyword( Keyword );
      }
      else {
        Books = this._bookRepository.GetAllBooks();
      }
    }
  }
}

 

最後在「ListModel」類別的「OnGet」方法中判斷使用者是否有出入查詢關鍵字,根據篩選條件,回傳滿足條件的圖書資料,若沒有輸入查詢關鍵字,則回傳所有圖書資料。

選取Visual Studio開發工具「Build」-「Build Solution」項目編譯目前的專案,確認程式碼能正確編譯。在Visual Studio開發工具,按CTRL+F5執行網站,選取「Books」連結,執行結果參考如下圖所示:

clip_image002

圖 1:使用表單傳送查詢關鍵字。

在表單中的文字方塊輸入查詢關鍵字,如「Beauty」,然後按下「Submit」按鈕,此時便將輸入的資料轉換成查詢字串:

https://localhost:44300/Books/List?Keyword=Beauty

然後篩選出滿足條件的圖書資料,請參考下圖所示:

clip_image004

圖 2:篩選出滿足條件的圖書資料。

Tags:

.NET Magazine國際中文電子雜誌 | ASP.NET Razor Pages | 許薰尹Vivid Hsu

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List