因為要導航到Edit的View,把以接下來我們建立Edit的Action和View(因為在編輯資料時,要用到驗證,Edit才是我們的重點)。
public ActionResult Edit(int id)
{
var list = DCDC.news.Single(newss=>newss.ID ==id);
return View(list);
}
<%= Html.ActionLink("Edit", "Edit", new { id=item.ID }) %>中的id會被當成參數送到EditController的Edit(int id)的Action,成為Edit方法的實參。
Edit.aspx頁面如下圖:
對應Edit的Action生成view,代碼如下:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcCompany.Models.news>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
編輯
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2 style ="text-align :left ;">編輯</h2>
<%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>
<% using (Html.BeginForm())
{ %>
<fieldset>
<legend>詳細内容</legend>
<p>
<label for="title">标題:</label>
<%= Html.TextBox("title", Model.title) %>
<%= Html.ValidationMessage("題目", "*")%>
</p>
<label for="datetimes">時間:</label>
<%= Html.TextBox("datetimes", String.Format("{0:g}", Model.datetimes)) %>
<%= Html.ValidationMessage("時間", "*") %>
<label for="contents">内容:</label>
<%= Html.TextBox("contents", Model.contents) %>
<%= Html.ValidationMessage("内容", "*")%>
<input type="submit" value="更新" />
</fieldset>
<% } %>
<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>
如果要單擊“更新”傳回資料新資料,還需要我們寫如下一個Action:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id,FormCollection formValuews)
news Sig_news = DCDC.news.Single(newss => newss.ID == id);
try
{
Sig_news.title = formValuews.GetValue("title").AttemptedValue;
Sig_news.datetimes = DateTime.Parse(formValuews.GetValue("datetimes").AttemptedValue);
Sig_news.contents = formValuews.GetValue("contents").AttemptedValue;
DCDC.SubmitChanges();
return RedirectToAction("Index");
}
catch
{
foreach (var v in Sig_news.GetRuleViolations())
{
ModelState.AddModelError(v.PropertyName,v.ErrorMessage);
}
return View(Sig_news);
}
這個Edit的Action是使用者送出返來更新資料庫的,我們可以從formValuews得到使用者在頁面上更新的資料,來更新Sig_news對象,然後調用DCDC.SubmitChanges();去更新資料庫,如果沒有民常,會導航到index.aspx頁面。如果發生異常,就會運作到catch裡。如果還記得,在本文的前半部分,我們說到OnValidate,是資料在送出時應該驗證,但在這裡,我們并沒有顯示的調用OnValidate這個方法,但實際運作中,我們發現,這個方法被執行了,如果我們建立跟蹤,把斷點設在DCDC.SubmitChanges();如果我們資料有民常,會發現當DCDC.SubmitChanges();執行完後就會跳到partial void OnValidate(System.Data.Linq.ChangeAction action)這個方法,這是怎麼做到的呢?我們猜測,一定是在資料送出時,調用OnValidate這個方法。為了找到它們的關系,隻好用Reflector.exe來“探測”一下了(Reflector.exe的用法就不說了)。
SubmitChanges方法是DataContext的一個方法,這個類位于System.Data.Linq命空間下,用Reflector.exe打開SubmitChanges,看到this.SubmitChanges(ConflictMode.FailOnFirstConflict);定位這個方法,可以看到new ChangeProcessor(this.services, this).SubmitChanges(failureMode);定位查找會發現ValidateAll(orderedList);在這個方法中,多處看到 SendOnValidate(obj2.Type, obj2, ChangeAction.Insert);這個方法,再定位,有這樣一行代碼 type.OnValidateMethod.Invoke(item.Current, new object[] { changeAction });這裡,正是通過反射調用了OnValidate這個方法。這樣我們就找到了SubmitChanges執行時調用OnValidate的方法了(其不用調用OnValidate也可以驗證使用者資料,隻需要寫個方法,在SubmitChanges 送出以前執行就可以達到同樣效果)。同時,當發生異常時,OnValidate會抛出一個Application的異常,這裡會被public ActionResult Edit(int id,FormCollection formValuews)方法中的Catch捕獲到,就執行如下代碼:
foreach (var v in Sig_news.GetRuleViolations())
this.ModelState.AddModelError(v.PropertyName,v.ErrorMessage);
這行代碼的意思是把錯誤的資訊,以鍵值的方式放入ModelState中,ModelState是一個ModelStateDictionary類型,這個類型實作了IDictionary<string, ModelState>, ICollection<KeyValuePair<string, ModelState>>, IEnumerable<KeyValuePair<string, ModelState>>, IEnumerable這些接口(這裡要注意,ModelState是目前對象的一個屬性,并且它的AddModelError方法的第一個參數key有其獨特的作用)。處理完異常後,還是傳回目前頁面。這時你會發現,在頁面的 <%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>發生了變化,把我們錯誤的地方去提示出來了,這裡就是,為什麼我們把錯誤資訊放到ModelState中,而錯誤則顯示在了Html.ValidationSummary中了呢?并且發生錯誤的資料後會加上了一個紅色的“*”,這是怎麼樣做到的呢?
再次利用Reflector.exe,檢視Html.ValidationSummary方法和Html.ValidationMessage方法,會發現它們顯示的資料是從ModelState 中擷取的,如果ModelState 這個集合中沒有資料,Html.ValidationSummary和Html.ValidationMessage就傳回空,如果發生異常,this.ModelState中有子項,就會通過Html.ValidationSummary和Html.ValidationMessage在頁面頁上顯示出來。因為Html.ValidationMessage在頁面上有多個,是以在this.ModelState.AddModelError(v.PropertyName,v.ErrorMessage);方法中的v.PropertyName就有了用處了,這個值要與<%= Html.ValidationMessage("題目", "*")%>中的第一個參數對應,這樣<%= Html.ValidationMessage("題目", "*")%>才能起到作用,顯示出第二個參數“*”。
這樣一來,就達到了ASP.NET MVC的資料驗證。由于ASPNET MVC 驗證捌的彎比較多,是以下來用個圖來說明一下。
<a href="http://down.51cto.com/data/2354001" target="_blank">附件:http://down.51cto.com/data/2354001</a>
本文轉自桂素偉51CTO部落格,原文連結:http://blog.51cto.com/axzxs/200783 ,如需轉載請自行聯系原作者