ASP.NET MVC案例教程(五)

來源:互聯網
上載者:User

資料驗證

在上一篇文章中,我們完成了發布公告的功能。但是從健壯性角度看,這個功能並不完善,因為一般情況下,我們輸入的資料要符合一定的約束條件,例如,在我們的例子中,我們至少不能將Null 字元串作為標題或內容吧。下面,我們來為程式加入資料驗證功能,

ASP.NET MVC中提供了良好的資料驗證實現支援,下面我們來看實現過程。首先,我們要修改一下Release.aspx視圖,修改後的視圖如下。

Release.aspx:

 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Release.aspx.cs" Inherits="MVCDemo.Views.Announce.Release" %> <%@ Import Namespace="MVCDemo.Models.Entities" %>  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server">     <title></title> </head><body>    <% SelectList categories = ViewData["Categories"] as SelectList; %>    <div>        <h1>MVC公告發布系統——發布公告</h1>        <% Html.BeginForm("DoRelease","Announce",FormMethod.Post); %>        <dl>            <dt>標題:</dt>            <dd><%= Html.TextBox("Title") %></dd>            <dd><%= Html.ValidationMessage("TitleValidator") %></dd>            <dt>分類:</dt>           <dd><%= Html.DropDownList("Category",categories) %></dd>                       <dd></dd>            <dt>內容:</dt>            <dd><%= Html.TextArea("Content") %></dd>            <dd><%= Html.ValidationMessage("ContentValidator") %></dd>        </dl>        <input type="submit" value="發布" />        <% Html.EndForm(); %>    </div></body></html>

可以看到,並沒有什麼大的變動,只是多了兩個Html.ValidationMessage方法。可以這樣理解,這個方法相當於產生一個span標籤,而這個span就是要顯示錯誤資訊的地方。這個方法接收一個參數,用來指明其在Controller中的名字。如果你對這個迷惑,不要緊,接下來看完Controller的代碼,你就什麼都清楚了。

AnnounceController.cs:

 using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using System.Web.Mvc.Ajax;using MVCDemo.Models;using MVCDemo.Models.Interfaces;using MVCDemo.Models.Entities;namespace MVCDemo.Controllers{public class AnnounceController : Controller{public ActionResult Release(){ICategoryService cServ = ServiceBuilder.BuildCategoryService();List categories = cServ.GetAll();ViewData["Categories"] = new SelectList(categories, "ID", "Name");return View("Release");}public ActionResult DoRelease(){if (String.IsNullOrEmpty(Request.Form["Title"]) || String.IsNullOrEmpty(Request.Form["Content"])){if (String.IsNullOrEmpty(Request.Form["Title"])){ViewData.ModelState.AddModelError("TitleValidator","公告標題不可為空!");}if (String.IsNullOrEmpty(Request.Form["Content"])){ViewData.ModelState.AddModelError("ContentValidator", "公告內容不可為空!");}return Release();}AnnounceInfo announce = new AnnounceInfo(){ID = 1,Title = Request.Form["Title"],Category = Int32.Parse(Request.Form["Category"]),Content = Request.Form["Content"],};IAnnounceService aServ = ServiceBuilder.BuildAnnounceService();aServ.Release(announce);ViewData["Announce"] = announce;return View("ReleaseSucceed");}}}

可以看到,我們的DoRelease這個Action方法多了不少東西。我們看多了什麼:當從表單傳遞過來的標題或內容為空白時,我們做了一定處理。注意,這個ViewData.ModelState.AddModelError方法,它就是往我們剛才說的由Html.ValidationMessage產生的span裡加入錯誤資訊的方法,它可以有兩個參數,第一個指明哪個span,這個參數Html.ValidationMessage中的參數是對應的。第二個參數就是要顯示的資訊。

相信結合視圖和控制器,已經很好理解了。最後,如果標題或內容有空值的話,我們不再調用商務邏輯組件處理了,而是調用了Release這個Action。為什麼我們不用Redirect呢?因為我們要保持ViewData中的資料,剛才我們的錯誤資訊可都放在裡面的,而使用了Redirect,ViewData的資訊就傳不過去了。

現在,我們再來發布公告。我們故意什麼都不填,提交,看結果:

沒有問題,我們的程式成功對標題和內容進行了完整性檢測(這裡就是均不可為空),在驗證不通過時,返回了發布公告視圖並正確顯示了錯誤提示資訊。

也許你有一個疑問,為什麼第一次請求Release視圖時沒有顯示任何錯誤資訊呢?因為那時ViewData中的ModelError是空的。而Html.ValidationMessage產生的標籤會自動尋找ModelError中同名的錯誤資訊,找不到,當然是空的了。而在提交空資訊時,DoRelease這個Action為ViewData的ModelError添加了內容,於是當再次返回Release視圖時,相應資訊就顯示在我們指定的位置了。

使用ASP.NET AJAX實現用戶端資料驗證

上面的代碼運行起來沒問題,也達到了我們的要求。但是驗證標題內容是否為空白這種行為在用戶端應該就可以完成。當然,為了放置惡意攻擊或瀏覽器將JavaScript屏蔽的情況,我們應該在後台進行驗證,但是我們不能每次都將這種請求發到後台去驗證,這太費資源了,畢竟惡意攻擊者和JavaScript被屏蔽的瀏覽器只是少數。所以,在資料被送到後台前,我們應該先進行一遍驗證,這樣可以節約很多資源。

下面,我們使用ASP.NET AJAX架構完成用戶端的資料驗證。

說實話,在ASP.NET MVC中使用ASP.NET AJAX或JQuery實在太方便了,不信你展開Scripts檔案夾,看到沒,微軟已經把這些庫放到裡面了,所以,我們要做的只是直接引用。看我們修改後的Release.aspx。

Release.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Release.aspx.cs" Inherits="MVCDemo.Views.Announce.Release" %><%@ Import Namespace="MVCDemo.Models.Entities" %>  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server">     <title></title>     <script type="text/javascript" src="<%= Url.Content("~/Scripts/MicrosoftAjax.debug.js") %>"></script>    <script type="text/javascript" src="<%= Url.Content("~/Scripts/MicrosoftAjaxValidate.js") %>"></script></head><body>    <% SelectList categories = ViewData["Categories"] as SelectList; %>    <div>        <h1>MVC公告發布系統——發布公告</h1>        <% Html.BeginForm("DoRelease","Announce",FormMethod.Post); %>        <dl>            <dt>標題:</dt>            <dd><%= Html.TextBox("Title") %></dd>            <dd><span id="TitleValidator"></span></dd>            <dt>分類:</dt>            <dd><%= Html.DropDownList("Category",categories) %></dd>            <dd></dd>            <dt>內容:</dt>            <dd><%= Html.TextArea("Content") %></dd>            <dd><span id="ContentValidator"></span></dd>        </dl>        <input id="Submit" type="submit" value="發布" />        <% Html.EndForm(); %>    </div></body></html>

改動有兩處,首先我們在頁頭引用了兩個js檔案,第一個是ASP.NET AJAX的庫檔案,第二個就是我們一會要實現的包含驗證代碼的js檔案了。你可能注意到那個Url.Content了,Url是ViewPage的一個對象,它最常用的一個方法就是Content,它的功能是返回某個檔案的路徑。一般情況下,在使用了ASP.NET MVC後,目錄結構變得有點詭異,像js、css、圖片等與路徑(即使是相對路徑)引用相關的地方可能會出現問題,但是,只要你在這些地方用Url.Content產生路徑,而不是直接將路徑寫在頁面裡,一般就沒什麼問題了。所以,凡是引用js、css、圖片等除,請一定使用Url.Content產生路徑,其參數只有一個,就是檔案原始的相對路徑。

下一個改動就是顯示錯誤資訊的span不再是Html.ValidationMessage產生的了,而是普通的span。

下面我們在Scripts目錄下建立MicrosoftAjaxValidate.js檔案。

MicrosoftAjaxValidate.js:

 Sys.Application.add_init(onPageInit);function onPageInit() {$addHandler($get("Submit"), "click", validate);}function validate() {if ($get("Title").value == "" || $get("Content").value == "") {if ($get("Title").value == "") {$get("TitleValidator").innerHTML = "標題不可為空!";}if ($get("Content").value == "") {$get("ContentValidator").innerHTML = "內容不可為空!";}return false;}return true;}

關於這段代碼我不多說了,對ASP.NET AJAX有興趣的可以參看《ASP.NET AJAX用戶端編程之旅》系列文章。

現在運行,將標題和內容留空,提交。OK!效果和剛才很像,只不過這次是在用戶端驗證了,並沒有提交到伺服器端。

整合JQuery

下面我們再使用JQuery實現這個功能。

其實看懂上面的實現後,我想你已經想到怎麼整合JQuery了,無非也是引入相應庫和js檔案,然後使用JQuery編寫驗證代碼。修改後的Release.aspx就沒必要看了,無非是引入Scripts目錄下的JQuery庫,然後再引入一個自訂驗證js檔案,我們姑且叫JQueryValidate.js吧。

下面在Scripts目錄下建立JQueryValidate.js,代碼如下:

JQueryValidate.js:

 $(document).ready(function(){     $("#Submit").click(function() {         if ($("#Title").attr("value") == "" || $("#Content").attr("value") == "") {             if ($("#Title").attr("value") == "") {                 $("#TitleValidator").attr("innerHTML", "標題不可為空!");             }             if ($("#Content").attr("value") == "") {                 $("#ContentValidator").attr("innerHTML", "內容不可為空!");             }            return false;        }        return true;    }    );});

小結

從本文可以看出,在MVC架構中整合Ajax和普通應用差別不大,唯一就是注意在引用外部js時使用Url.Content方法處理一下相對路徑。其實在本文中我們並沒有使用到Ajax,而僅僅是整合了JavaScirpt,但是這已經足夠了,因為Ajax無非就是在這些JavaScript裡包含了非同步後台調用。

其實,ASP.NET MVC有專門針對ASP.NET AJAX的擴充,放在MicrosoftMvcAjax.js裡。而在ViewPage裡有個叫Ajax的AjaxHelper對象,可以實現一些簡單的非同步呼叫。但是這個擴充的功能很有限,有興趣的可以自己研究一下。我個人還是建議大家自己寫JS代碼,當然可以使用ASP.NET AJAX或JQeury這樣優秀的架構。

這篇文章先到這裡,下一篇中我們討論一下攔截器的使用。

本文出自張洋部落格T2's Notebook

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.