學習ASP.NET MVC(七)——我的第一個ASP.NET MVC 查詢頁面


 學習ASP.NET MVC 編程系列目錄

學習ASP.NET MVC(一)——我的第一個ASP.NET MVC應用程序

學習ASP.NET MVC(二)——我的第一個ASP.NET MVC 控制器

學習ASP.NET MVC(三)——我的第一個ASP.NET MVC 視圖

學習ASP.NET MVC(四)——我的第一個ASP.NET MVC 實體對象

學習ASP.NET MVC(五)——我的第一個ASP.NET MVC CURD頁面

學習ASP.NET MVC(六)——我的第一個ASP.NET MVC 編輯頁面

學習ASP.NET MVC(七)——我的第一個ASP.NET MVC 查詢頁面

學習ASP.NET MVC(八)——“Code First Migrations ”工具

學習ASP.NET MVC(九)——“Code First Migrations ”工具使用示例

學習ASP.NET MVC(十)——排序

學習ASP.NET MVC(十一)——分頁

 

       在本篇文章中,我將添加一個新的查詢頁面(SearchIndex),可以按書籍的種類或名稱來進行查詢。這個新頁面的網址是http://localhost:36878/Book/ SearchIndex。該頁面中用一個下拉框來顯示種類,用一文本框讓用戶輸入書籍的名稱。當用戶在點擊“查詢”按鈕之后,頁面會被刷新,顯示用戶的查詢結果。控制器會根據用戶提交查詢參數,由動作方法(Action Motehd)去解析用戶提交的參數值,並使用這些值來查詢數據庫。

第一步,創建SearchIndex查詢頁面
            首先,在BookController中添加一個SearchIndex動作方法。該方法將返回一個包含HTML表單的視圖。代碼如下:

public ActionResult SearchIndex(string searchString)
        {

           var books = from m in db.Books
                        select m;

           if (!String.IsNullOrEmpty(searchString))
           {

                books = books.Where(s => s.Name.Contains(searchString));

            }
            return View(books);
        }

        上面SearchIndex方法代碼中的第一行如下面,其作用是創建一個LINQ查詢從數據庫中篩選相應的書籍數據:

           var books = from m in db.Books
                       select m;

       這一句表示查詢已經建立,但是尚未對數據存儲區中的數據進行篩選。 
       如果“searchString”參數變量中有一個字符串,則這個“books”查詢語句將以“searchString”參數變量的值做為查詢條件進行篩選相應的書籍數據,如下面的代碼:

   if (!String.IsNullOrEmpty(searchString))
            {
               books = books.Where(s => s.Name.Contains(searchString));

            }

       上面代碼中的s =>s.Title代碼是一個Lambda表達式。 Lambda 表達式用在基於方法的 LINQ 查詢中,作為諸如 Where 和 Where 等標准查詢運算符方法的參數。  例如上面的代碼中使用的方法。LINQ查詢時未執行它們的定義,或者當他們通過調用一個方法進行修改,或在排序時進行修改。相反,查詢執行的延遲,這意味着一個表達式的計算被延遲,直到其變量實際上的迭代結束或者可以調用的方法(ToList方法)被調用。在SearchIndex這個頁面中,查詢是在SearchIndex視圖下執行。

       接下來,我們來制作一個SearchIndex視圖,以將這個查詢界面呈現給用戶看。在Visual Studio中的BookController文件中右鍵單擊里面的SearchIndex方法,在彈出菜單中單擊“添加視圖”菜單。在添加視圖對話框中,指定你要一個Book對象傳遞給視圖模板作為它的模型類。在支架模板列表中,選擇列表,然后單擊“添加”。如下圖。

 

 

        當單擊“添加”按鈕,將創建一個Views\Book\ SearchIndex.cshtml視圖模板。因為你選擇了列表中的支架模板列表中,Visual Studio會自動生成(搭建)的視圖中的一些默認的標記。基架創建一個HTML表單。它檢查Book類和創建的代碼來呈現為類的每個屬性<label>元素。下面的清單顯示生成的創建視圖:

 

@model IEnumerable<MvcApplication1.Models.Book>

@{

    ViewBag.Title = "書籍查詢";

}

<h2>書籍查詢</h2>
<p>

    @Html.ActionLink("Create New", "Create")

</p>

<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Category)

        </th>

        <th>

            @Html.DisplayNameFor(model => model.Name)

        </th>
        <th>
            @Html.DisplayNameFor(model => model.Numberofcopies)

        </th>
        <th>
            @Html.DisplayNameFor(model => model.AuthorID)

        </th>

        <th>

            @Html.DisplayNameFor(model => model.Price)

        </th>
        <th>
            @Html.DisplayNameFor(model => model.PublishDate)

        </th>

        <th></th>

    </tr> 

@foreach (var item in Model) {

    <tr>

        <td>

            @Html.DisplayFor(modelItem => item.Category)

        </td>

        <td>

            @Html.DisplayFor(modelItem => item.Name)

        </td>

        <td>

            @Html.DisplayFor(modelItem => item.Numberofcopies)

        </td>

        <td>

            @Html.DisplayFor(modelItem => item.AuthorID)

        </td>

        <td>

            @Html.DisplayFor(modelItem => item.Price)

        </td>

        <td>

            @Html.DisplayFor(modelItem => item.PublishDate)

        </td>

        <td>

            @Html.ActionLink("Edit", "Edit", new { id=item.BookID }) |

            @Html.ActionLink("Details", "Details", new { id=item.BookID }) |

            @Html.ActionLink("Delete", "Delete", new { id=item.BookID })

        </td>

    </tr>

}
</table>

 

      按F5, 運行該應用程序,並使用瀏覽器導航到/Book/ SearchIndex。在URL后面會追加一個查詢字符串,如“?searchString=sql”。提交之后,符合條件的書籍數據將顯示。如下圖。

 


 第三,修改SearchIndex查詢方法
        我們也可以修改SearchIndex方法的參數,傳入一個命名參數“ID”,這個“ID”參數將匹配在Global.asax文件中的缺省路由設置中的{id}占位符。路由設置如下: 

{controller}/{action}/{id}

原來SearchIndex方法如下所示:

public ActionResult SearchIndex(string searchString)
      {

            var books = from m in db.Books

                         select m;

            if (!String.IsNullOrEmpty(searchString))

            {

                books = books.Where(s => s.Name.Contains(searchString));

            }

            return View(books);
        }

       修改后的SearchIndex方法將如下所示:

public ActionResult SearchIndex(string id) 
{ 

      string searchString = id;
            var books = from m in db.Books
                        select m;

            if (!String.IsNullOrEmpty(searchString))
            {

                books = books.Where(s => s.Name.Contains(searchString));

            }

            return View(books);
}

 
         現在,您可以把查詢條件“書籍名稱”作為路由數據(URL中的一段字符),而不是作為查詢字符串值。如下圖。

 

       第三,添加“書籍名稱”查詢條件
     通過上面的學習,我們實現了數據查詢功能。但是我們不能希望普通用戶也能像我們一樣,會在URL中添加查詢條件。當需要進行查詢時,自己去修改URL中的查詢條件內容來進行書籍查詢。所以,需要添加一個查詢頁面,方便普通用戶輸入相應的查詢條件,根據查詢條件去查詢書籍。

       一、改變SearchIndex方法的簽名,並通過路由綁定到ID參數上,讓SearchIndex方法接受一個名為“searchString”字符串作為參數。代碼如下:

public ActionResult SearchIndex(string searchString) 
{           

       var books = from m in db.Books

                         select m;

            if (!String.IsNullOrEmpty(searchString))

            {

                books = books.Where(s => s.Name.Contains(searchString));

            }
            return View(books);

}

 

        二、打開Views\Book\ SearchIndex.cshtml文件,在@Html.ActionLink("Create New", "Create")的位置處,添加一個文本框與一個查詢按鈕。內容如下: 

@using (Html.BeginForm())
   {    

         <p> 書籍名稱: @Html.TextBox("SearchString")<br />  

         <input type="submit" value="查詢" /></p> 

        }

        下面的代碼顯示了Views\Book\ SearchIndex.cshtml文件的一部分與增加的篩選標記。 

@Model IEnumerable<MvcApplication1.Models.Book>

@{
    ViewBag.Title = "書籍查詢";
}

<h2>書籍查詢</h2>
   @using (Html.BeginForm())

   {    

         <p> 書籍名稱: @Html.TextBox("SearchString")<br />  

         <input type="submit" value="查詢" /></p> 

        }


        這個Html.BeginForm輔助方法創建了一個<form>標簽。當用戶通過單擊“查詢”按鈕提交表單時,Html.BeginForm輔助方法將會把這個Form中的內容提交給控制器,同時刷新頁面。
       三、按F5運行該應用程序,並在“書籍名稱”文本框中輸入“sql”,然后點擊“查詢”按鈕,進行書籍查詢。如下圖。

       還有不需要重載SearchIndexHttpPost的方法。因為該方法不改變應用程序的狀態,只是是用來查詢數據。 
       你可以象下面一樣把[HttpPost]加在SearchIndex方法的上面。在添加了[HttpPost]之后,瀏覽器將首先調用匹配HttpPostSearchIndex方法。HttpPostSearchIndex方法運行結果如下圖。

[HttpPost] 

public string SearchIndex(FormCollection fc, string searchString) 
{ 

    return "<h3> From [HttpPost]SearchIndex: " + searchString + "</h3>"; 

}

         然而,即使添加了SearchIndex的HttpPost版本的方法。假設一下如下場景,你想把某個查詢結果發給你的朋友,你又想只發一個特定鏈接給朋友,讓他們可以查詢查看相同的一個查詢結果。請注意,如果是相同的查詢結果,一個為HTTP POST請求,另一個為相同的URL GET請求(例如本地主機:XXXXX /圖書/ SearchIndex ) 。則HTTP POST請求在URL本身沒有帶查詢參數的情況下,是無法看到查詢結果的。如果只是一個URL,這就意味着你與朋友們永遠不能看到相同的查詢結果。
        你應該使用以下的解決方案,使用BeginForm的重載方法,指定POST請求應該在URL中添加的相應的查詢參數信息 ,它應該被路由到SearchIndex方法的HTTPGET版本。使用下面的代碼替換現有參數的BeginForm方法將:如下圖。

   @using (Html.BeginForm("SearchIndex", "book", FormMethod.Get))

 
       現在,當你點擊“查詢”按鈕時,URL中將包含查詢條件的字符串。查詢請求也將去請求HTTPGET的 SearchIndex操作方法,即使你有一個HttpPost的SearchIndex方法。如下圖。

 

第三,添加“書籍種類”查詢方法
      第一步,刪除代碼中HttpPost版本的SearchIndex方法。 

       第二步,添加新的查詢功能。在頁面中添加一個“書籍種類”的查詢條件,讓用戶可以通過“書籍種類”查詢到相關書籍。用下面的代碼替換SearchIndex方法:

   public ActionResult SearchIndex(string Category, string searchString)
  {

            var cateLst = new List<string>();
            var cateQry = from d in db.Books

                           orderby d.Category

                           select d.Category;

            cateLst.AddRange(cateQry.Distinct());

            ViewBag.category = new SelectList(cateLst);

            var books = from m in db.Books

                         select m;

            if (!String.IsNullOrEmpty(searchString))
           {
                books = books.Where(s => s.Name.Contains(searchString));

            }

            if (string.IsNullOrEmpty(Category))

                return View(books);

            else

            {
                return View(books.Where(x => x.Category == Category));
            }
        }

 

      這個新的SearchIndex方法增加了一個新的查詢條件,即Category。代碼的前幾行創建一個List對象從數據庫中查詢“書籍種類”,並將查詢到的結果添加到List對象中。

       下面的代碼是通過一個LINQ查詢從數據庫把所有書籍種類都查了出來。  

var cateQry = from d in db.Books

                           orderby d.Category

                           select d.Category;


        以下代碼的作用是使用泛型List集合的AddRange方法所有書籍類型添加到列表中。 (如果沒有DISTINCT修飾符,會將相同的類型增加到列表中 - 例如,MS,SAP將會被我們添加兩次)。

 cateLst.AddRange(cateQry.Distinct());

      然后,該代碼存儲在ViewBag對象流派列表。 

  ViewBag.category = new SelectList(cateLst);


     下面的代碼演示如何檢查Category參數。如果它不是空的,該代碼進一步限制了書的查詢所選擇的書限制到指定的種類。      

 if (string.IsNullOrEmpty(Category))

                return View(books);
            else
            {
                return View(books.Where(x => x.Category == Category));
            }

           第四,在SearchIndex查詢頁面中添加“書籍種類”查詢條件 
          添加一個HTML樣式的下拉列表框(DropDownList)到Views\Book\ SearchIndex.cshtml文件中,放在“書籍名稱”文本框的前面。已完成的代碼如下所示:

<p> 

     @using (Html.BeginForm("SearchIndex","book",FormMethod.Get)){     

         <p>書籍種類: @Html.DropDownList("category", "All")   

           書籍名稱: @Html.TextBox("SearchString")   

         <input type="submit" value="查詢" /></p> 

        } 

</p>

        按F5,運行這個應用程序,在瀏覽器中瀏覽/Book/ SearchIndex這個地址。就可以按“書籍種類”、“書籍名稱”進行書籍信息查詢。如下圖1,圖2。
 

圖1

 

圖2
 在本篇中學習如何創建一個新的查詢操作方法和視圖,讓用戶通過書籍名稱和書籍類型來進行查詢。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM