免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
ASP.NET MVC4 IN ACTION學(xué)習(xí)筆記

ASPNET MVC4 視圖基礎(chǔ)(Views fundamentals)

--忽然發(fā)現(xiàn)我的時(shí)間不夠了,但是我還是完成了

原著:ASP.NET MVC 4 IN ACTION

本人能力有限,盡量將書(shū)中的知識(shí)濃縮去講,仔細(xì)學(xué)過(guò)后,然后你再學(xué)習(xí)其他語(yǔ)言的MVC框架也就大同小異了

本次覆蓋知識(shí)點(diǎn):

  1. 1. 把數(shù)據(jù)傳遞給視圖 (Providing data to the view )
  2. 2. 使用強(qiáng)類型視圖 (Using strongly typed views)
  3. 3. 使用視圖助手對(duì)象 (Understanding view helper objects)
  4. 4. 用模版開(kāi)發(fā) (Developing with templates)

 


 

      視圖(Views)是ASP.NET MVC 應(yīng)用程序起決定性的一部分--它提供了一個(gè)很簡(jiǎn)潔的方式,在你的應(yīng)用程序中,邏輯中涉及到展現(xiàn)頁(yè)面的部分分離出來(lái)了。在上一章中的我們的Guestbook應(yīng)用程序中,我們用Razor模版引擎寫了一些簡(jiǎn)單的視圖,稍微了解了一點(diǎn),最后,我們學(xué)習(xí)了layouts是如何讓你的應(yīng)用程序中的所有頁(yè)面保持一致的風(fēng)格,結(jié)束了上章的課程。

沒(méi)有學(xué)過(guò)的,上章飛機(jī)票:點(diǎn)開(kāi)學(xué)習(xí)

      在本章中,我們將再稍微深入學(xué)習(xí)一下視圖---我們將會(huì)研究一下ASP.NET MVC如何呈現(xiàn)視圖,然后我們?cè)倏聪掳褦?shù)據(jù)傳給視圖的其他不同的一些方法。最后,我們?cè)僦v一下原來(lái)在 ASP.NET MVC 2 中介紹過(guò)的一些模版(temlate)特征,為了分析講解這些特征,我們一開(kāi)始就會(huì)在我們的Guestbook應(yīng)用程序中添加一個(gè)編輯頁(yè)面。

3.1  視圖介紹

    視圖的職責(zé)看似簡(jiǎn)單。它的目標(biāo)是與相對(duì)應(yīng)的模型(Model)相關(guān)聯(lián),并使用對(duì)應(yīng)的模型來(lái)呈現(xiàn)內(nèi)容。由于控制器(Controller)和相關(guān)聯(lián)的服務(wù)已經(jīng)處理了所有的業(yè)務(wù)邏輯,并且把處理后的結(jié)果封裝成了模型對(duì)象,而視圖只需要知道怎樣把這個(gè)模型轉(zhuǎn)換成HTML來(lái)呈現(xiàn)就行了。

   盡管這種職責(zé)關(guān)系的分離可能,對(duì)傳統(tǒng)的ASP.NET應(yīng)用程序編程人員來(lái)說(shuō)編寫造成了麻煩和困擾,但是視圖你還是要編寫的。為了保證你的視圖不會(huì)太復(fù)雜而很難去維護(hù),所以對(duì)于視圖,你還是要小心仔細(xì)的,要有意的去設(shè)計(jì)它.

   在我們學(xué)習(xí)“如何把數(shù)據(jù)傳遞給視圖”的方法之前,我們先研究一下MVC框架是怎樣把視圖給呈現(xiàn)的。

 

   3.1.1 選擇一個(gè)視圖去展示

     在上一章里面我們通過(guò)調(diào)用一個(gè)控制器里面的一個(gè)action中的一個(gè)View方法來(lái)讓頁(yè)面呈現(xiàn)了。下面這個(gè)是我們的GuestbookController控制器里的Create操作:

    

   通過(guò)這些代碼, Views/Guestbook/Create.csthml 這個(gè)視圖文件就會(huì)被呈現(xiàn)。但是在這個(gè)應(yīng)用程序中,MVC框架怎么知道去呈現(xiàn)這個(gè)指定的視圖,而不是其他視圖,比如說(shuō)Index.cshtml的呢?

   調(diào)用View方法將會(huì)返回一個(gè) 知道怎么去呈現(xiàn)指定的視圖的ViewResult對(duì)象。當(dāng)調(diào)用View的無(wú)參數(shù)方法時(shí),MVC框架就會(huì)認(rèn)為你要呈現(xiàn)的視圖的名字跟這個(gè)方法所在的action(Create)名字一樣。之后,MVC框架的ControllerActionInvoker類就會(huì)去調(diào)用ViewResult類,然后把呈現(xiàn)頁(yè)面的責(zé)任轉(zhuǎn)交給了它。在這個(gè)時(shí)候,這個(gè)框架也會(huì)命令ViewEngineCollection去查找要呈現(xiàn)的頁(yè)面的位置。(回顧一下上一章的內(nèi)容。這個(gè)視圖引擎默認(rèn)會(huì)在 Views/<Controller Name>目錄和Views/Shared目錄)

   視圖引擎

    不同的視圖引擎會(huì)有它不同的格式去呈現(xiàn)視圖,默認(rèn) ASP.NET MVC有兩個(gè)視圖引擎-RazorViewEngine和WebFormViewEngine。Razor視圖引擎的格式是cshtml文件或者vbhtml文件,然而WebForm視圖引擎依舊支持老格式的Web Form視圖(aspx頁(yè)面和.ascx文件)。以前的ASP.NET MVC版本默認(rèn)都只包括WebForm視圖引擎。

    為什么在ASP.NET MVC3中要引入新的視圖引擎呢?隨著ASP.NET 1.0的發(fā)行的開(kāi)始,Web Form就允許把代碼和標(biāo)簽寫在一個(gè)aspx頁(yè)面里面,但是把C#代碼寫在aspx頁(yè)面里面,控件的邏輯寫法在通常的開(kāi)發(fā)中嚴(yán)重受到阻礙。取而代之的是,開(kāi)發(fā)者們努力去把所有的邏輯放在了頁(yè)面的后面(代碼后置)。隨著ASP.NET 的發(fā)布,在aspx文件中增加了數(shù)據(jù)綁定,其他更新的模塊都去適應(yīng)配合控件開(kāi)發(fā)的模式。

    在許多MVC的框架里,視圖開(kāi)發(fā)都鼓勵(lì)和要求代碼,直接用標(biāo)簽去寫(也就是不用控件),由于ASPX視圖引擎在設(shè)計(jì)時(shí)沒(méi)有達(dá)到這個(gè)目標(biāo),所以ASP.NET團(tuán)隊(duì)決定去設(shè)計(jì)一個(gè)全新的視圖引擎--把代碼寫在模版里的一種模式。這是一種更智能的引擎,引擎能夠很容易地識(shí)別出標(biāo)簽的開(kāi)始和結(jié)束,而且開(kāi)發(fā)者也不用寫的那么復(fù)雜。

當(dāng)然你也可以用別的第三方的視圖引擎,在第10章,我們就會(huì)去看一下現(xiàn)在比較流行的Spark視圖引擎。

   3.1.1 重寫View

      如果你不想你的視圖名字跟action一樣。你可以使用View的重載方法。例如

     return View("New");   查找路徑 Views/<Controller Name>/New.cshtml和Views/Shared目錄,而不再是action的名字了

     你還可以寫路徑,就可以脫離默認(rèn)的控制名了的路徑限制了

     return View(("~/Views/SomeOtherDirectory/New.cshtml");

   3.1.2 把數(shù)據(jù)傳給視圖

      我們還是在我們的Guestbook案例上繼續(xù)編寫。上篇代碼案例

     我們將要講一下把數(shù)據(jù)傳給視圖的3種不同的方法---ViewDataDictionary,ViewBag,強(qiáng)類型視圖

   3.2.1 ViewDataDictionary

      把數(shù)據(jù)傳遞給視圖過(guò)去經(jīng)常使用的最主要的對(duì)象就是ViewDataDictionary

     和其他MVC框架一樣,ASP.NET MVC也暴露一個(gè)集合:可以把更多的model對(duì)象傳遞給視圖使用,然后視圖可以利用model里面封裝好的信息來(lái)展示信息。

     比如說(shuō),我們可以拓展我們的guestbook頁(yè)面---所有人都可以查看guestbook,但是只有當(dāng)前登錄的用戶可以編輯guestbook entries(guestbook中的一個(gè)實(shí)體對(duì)象,也就是一條記錄)。為了可以達(dá)到這個(gè)目的,我們可以通過(guò)GuestbookEntry對(duì)象,代碼如下:

    

    盡管,這個(gè)GuestbookEntry類已經(jīng)包括了所有我們要在使用GuestbookEntry的頁(yè)面上展示的數(shù)據(jù)了,但是它不包括當(dāng)前登錄的用戶的信息,或者不能決定視圖是否顯示Edit超鏈接。我們需要給視圖更多的信息,不能僅僅靠GuestbookEntry來(lái)做這個(gè)決定。我們可以使用ViewDataDictionary來(lái)提供更多的信息,代碼如下

public ActionResult Show(int id) {
            var entry = _db.Entries.Find(id);  //找到該Id的Entries
            bool hasPermission = User.Identity.Name == entry.name; //如果登陸人的姓名等于entry錄入人的姓名,就顯示Edit按鈕
            ViewData["hasPermission"] = hasPermission;
            return View(entry);
        }

添加到Controllers/GuestbookController.cs這個(gè)文件里面

在Controller里面我們可以直接使用ViewData,因?yàn)镃ontroller繼承ControllerBase類,ControllerBase下面有ViewData屬性。我們通過(guò)比較GuestbookEntry的name和當(dāng)前登錄用戶的name是否一樣,然后比較結(jié)果放在hasPermission里面,然后視圖那邊查看hasPermission是true還是false來(lái)決定是否顯示Edit超鏈接。

添加Show視圖,右鍵action名稱,添加視圖,然后直接點(diǎn)添加

視圖里面代碼如下:

@{
    ViewBag.Title = "Show";
}
 
<p>
    @{
        bool hasPermission = (bool)ViewData["hasPermission"];
    }
    @if (hasPermission)
    { 
        @Html.ActionLink("Edit", "Edit", new { id = Model.Id });
    }
    @Html.ActionLink("返回 Entries","Index")
</p>
 
 

現(xiàn)在我們來(lái)運(yùn)行我們的項(xiàng)目:如果是從我的csdn上下載的,默認(rèn)里面有3條數(shù)據(jù)了。

運(yùn)行的時(shí)候,我們手動(dòng)在地址欄的后面輸入Guestbook/Show/1,其中1是entry的id號(hào),在controller里面我們不是留了一個(gè)參數(shù)嗎?在Asp.NET MVC中,你可以這樣傳遞參數(shù),完整模擬路徑如下

http://localhost:端口號(hào)/Guestbook/Show/1

跳轉(zhuǎn)后,頁(yè)面默認(rèn)如下:因?yàn)槟氵€沒(méi)有登錄,所以不會(huì)顯示Edit超鏈接

數(shù)據(jù)庫(kù)中的表數(shù)據(jù)一覽,目前id只有1,2,3,所以測(cè)試的時(shí)候,不要輸入其他的

 

①輸入地址后,顯示效果如下

測(cè)試我們先注冊(cè)一個(gè)用戶,名字叫 茗洋芳竹,密碼叫123456

注冊(cè)好了,會(huì)自動(dòng)登陸

輸入Show/2,因?yàn)閕d=2的信息是  name等于茗洋芳竹,是本人,所以顯示了Edit超鏈接

 

 
 

我猜想,如果你以前做過(guò)WebForm的話,聰明的你肯定已經(jīng)領(lǐng)悟出來(lái)什么了.

 

3.2.2 ViewBag

    ViewDataDictionary一樣,ViewBag也是把數(shù)據(jù)傳遞給視圖使用的一種手段.ViewBag使用了C#4.0中的 的dynamic語(yǔ)法.

它不是使用key字符串在集合里存儲(chǔ)對(duì)象了,你可以在你的controller中簡(jiǎn)單的設(shè)置一下dynamic類型的ViewBag的一個(gè)屬性.

hasPermission是ViewBag的一個(gè)根本不存在的屬性,這里名字隨便取,因?yàn)閂iewBag是個(gè)dynamic類型的.不懂dynamic的可以查看一下C# dynamic資料

如果采用ViewBag的方式

那么Show頁(yè)面稍微改下就行了

原本代碼是這樣的

 

bool那里面的代碼可以不要了,if后面的那個(gè)條件,直接改成

就行了.

估計(jì)ViewBag你已經(jīng)會(huì)用了,Model從哪里來(lái)的,你先不用管,估計(jì)你也猜到了,我們?cè)贑ontroller中調(diào)用View()方法的時(shí)候,加了一個(gè)實(shí)體對(duì)象作為參數(shù).那么這里你就可以用Model來(lái)等效于你后臺(tái)傳來(lái)的實(shí)體對(duì)象那樣使用就行了.

盡管ViewData和ViewBag的都為解決數(shù)據(jù)傳遞視圖的問(wèn)題而提供了很多的靈活性,但是也因此付出了很大的代價(jià).如果你偶爾把一個(gè)dynamic屬性名稱敲寫錯(cuò)了,編譯的時(shí)候是找不到錯(cuò)誤的,這些技術(shù)所以也有不友好的地方.除此之外,在Visual Studio中 dynamic的屬性,編寫代碼時(shí)候是沒(méi)有提示的,ViewData也沒(méi)有,你要記得ViewData中的鍵名稱。(盡管有第三方企業(yè)工具:比如說(shuō)JetBrains ReSharper可以支持它)

 

除此之外,你也不能很容易地在dynamic屬性上綁定元數(shù)據(jù).而在ASP.NET MVC框架里面,你可以利用特性的優(yōu)勢(shì),直接把元數(shù)據(jù)綁定到現(xiàn)在比較常用的類型上(比如說(shuō),在System.ComponentModel.DataAnnotations命名空間下的驗(yàn)證特性,你可以用來(lái)標(biāo)記一個(gè)字段是否不能為空(required),一個(gè)字段的長(zhǎng)度限制等等),這些特性在dynamic的ViewBag屬性上都是不能使用的

取而代之的是,你可以使用強(qiáng)類型視圖,一個(gè)使用了強(qiáng)類型類的視圖.通過(guò)這個(gè)方法,你就可以利用vs獲得智能感知和vs的的重構(gòu)工具來(lái)高效快速的寫代碼了.你也可以用特性驅(qū)動(dòng)元數(shù)據(jù)的方法獲得好處.在下一節(jié)我們來(lái)研究一下.

 

3.2.3 強(qiáng)類型視圖,一個(gè)視圖模型

 當(dāng)你使用基于Razor的視圖的時(shí)候,你的視圖可以繼承兩種類型,默認(rèn)的是System.Web.Mvc.WebViewPage或者System.Web.Mvc.WebViewPage<T>,WebViewPage<T>繼承WebViewPage,所以提供了一些WebViewPage沒(méi)有的一些特征.

  下面是 WebViewPage<T>內(nèi)部骨架(Skeleton)的一些定義

 

  除了提供了強(qiáng)類型的ViewData.Model的包裝,然后你就可以使用Model外,WebViewPage<T>還提供了兩個(gè)可以在視圖中可以使用的AjaxHelper和HtmlHelper對(duì)象.

   為了使用強(qiáng)類型視圖,首先你要在你的Controller的action中設(shè)置ViewData.Model屬性,在Listing 3.4中,我們查出了所有的guestbook entries,然后展示在列表頁(yè)面上,在View方法中我們傳遞了一個(gè)實(shí)體.換句話說(shuō),也就是換個(gè)形式封裝設(shè)置了ViewData.Model屬性了,所以你在視圖頁(yè)面就可以直接使用Model屬性了.

 

我們修改GuestbookController中的Index操作和相對(duì)應(yīng)的視圖頁(yè)面(Guestbook/Index.cshtml)

 在Index視圖上就是用這個(gè)Action的.即使是一個(gè)弱類型的WebViewPage類,但是也可以使用ViewData.Model屬性的.但是這個(gè)屬性是一個(gè)類型對(duì)象,我們需要轉(zhuǎn)換一下結(jié)果才能有效的使用.取而代之,我們可以使用@model關(guān)鍵字來(lái)使我們的父類WebViewPage<T>指定model類型

  • @using GuestInfo.Models
  • @model List<GuestbookEntry>

通過(guò)使用@model關(guān)鍵字我們指定了model的類型,現(xiàn)在我們的視圖已經(jīng)繼承了于WebViewPage<T>而不是WebViewPage了.現(xiàn)在我們已經(jīng)有了一個(gè)強(qiáng)類型的視圖了.我們也可以使用@using關(guān)鍵字導(dǎo)入命名空間.在下一節(jié)里,我們將要看一下,在一個(gè)視圖里我們?cè)鯓邮褂胢odel對(duì)象來(lái)展示信息.

3.2.4 在一個(gè)視圖里面展示視圖model的數(shù)據(jù)

        在一個(gè)視圖里面展示信息,通常的,你可能使用HtmlHelper對(duì)象去輔助讓這個(gè)model生成html,思考一下下面一個(gè)展示了一個(gè)完整的Guestbook entry信息的代碼,這個(gè)代碼寫在Views/Guestbook/Show.cshtml

<h2>Guestbook Entry</h2>
<dl>
    <dt>姓名:</dt>
    <dd>@Model.Name</dd>
    <dt>日期:</dt>
    <dd>@Model.DateAdded</dd>
    <dt>消息:</dt>
    <dd>@Model.Message</dd>
</dl>
<p>
    @{
        bool hasPermission = (bool)ViewData["hasPermission"];
 
    }
    @if (ViewBag.hasPermission) //       ViewBag.hasPermission
    { 
        @Html.ActionLink("Edit", "Edit", new { id = Model.Id });
    }
    @Html.ActionLink("返回 Entries", "Index")
</p>

上面這段代碼我相信你們應(yīng)該能看懂了.看不懂的,在評(píng)價(jià)里面說(shuō)一下

當(dāng)我們?cè)谄聊簧险故疚淳幋a的用戶輸入的信息的時(shí)候,我們寧可不留出存在多種腳本攻擊的可能性.還好這個(gè)數(shù)據(jù)在呈現(xiàn)于屏幕之前已經(jīng)自動(dòng)編碼了.如果你想展示一個(gè)沒(méi)有編碼過(guò)的文本,你可以使用Html.Raw方法來(lái)使那些信息以純文本的形式展現(xiàn).

 

 

在login頁(yè)面里面,我們使用一個(gè)視圖model對(duì)象來(lái)表達(dá)了一個(gè)表單的全部的數(shù)據(jù),代碼如下

這個(gè)登陸頁(yè)面也非常簡(jiǎn)單,如下

 

 

由于在Log on屏幕里,我們選擇一個(gè)強(qiáng)類型視圖,我們使用了內(nèi)置的助手去幫助為每一個(gè)節(jié)點(diǎn)生成html.為了替換掉使用弱綁定來(lái)呈現(xiàn)action的參數(shù),我們可以使用基于表達(dá)式的HtmlHelper拓展來(lái)創(chuàng)建不同類型的input節(jié)點(diǎn),代碼如下(Views/Accout/register.cshtml)

@model GuestInfo.Models.RegisterModel
@{
    ViewBag.Title = "注冊(cè)";
}
 
<hgroup class="title">
    <h1>@ViewBag.Title.</h1>
    <h2>創(chuàng)建新帳戶。</h2>
</hgroup>
 
@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()
 
    <fieldset>
        <legend>注冊(cè)表單</legend>
        <ol>
            <li>
                @Html.LabelFor(m => m.UserName)
                @Html.TextBoxFor(m => m.UserName)
            </li>
            <li>
                @Html.LabelFor(m => m.Password)
                @Html.PasswordFor(m => m.Password)
            </li>
            <li>
                @Html.LabelFor(m => m.ConfirmPassword)
                @Html.PasswordFor(m => m.ConfirmPassword)
            </li>
        </ol>
        <input type="submit" value="注冊(cè)" />
    </fieldset>
}
 
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

 

其中這段代碼

功能類似于

<label for=”UserName”>姓名</label>

<input id=”UserName” name=”UserName” type=”text” value=”” />

由于這個(gè)label和input都可以用表達(dá)式(expression)來(lái)生成,所以我們不用再記復(fù)雜的label和input名稱了

HtmlHelper被設(shè)計(jì)時(shí)就支持強(qiáng)類型視圖

由于我們的表單都是使用強(qiáng)類型視圖生成的,所以我們?cè)赾ontroller中可以好好設(shè)計(jì)action,讓這個(gè)表單可以post提交上去.

而不是列舉每一個(gè)input字段作為一個(gè)action方法的參數(shù),我們可以綁定所有的參數(shù)給同一個(gè)view model(我們?cè)?jīng)想要展現(xiàn)的視圖)

在這里可以有兩個(gè)參數(shù),當(dāng)然你也可以有多個(gè).這里你也看到了,這里有個(gè)returnUrl,而不是表單中input節(jié)點(diǎn).第一個(gè)參數(shù),是一個(gè)model,封裝好了所有input中的值

隨著HtmlHelper對(duì)強(qiáng)類型視圖支持的越來(lái)越好,如果你只是僅僅依靠這些拓展來(lái)生成HTML,那么在你的視圖里面就會(huì)有一些重復(fù).舉個(gè)例子,如果每個(gè)input節(jié)點(diǎn)都想要一個(gè)對(duì)應(yīng)的label,那么為什么不能包括它呢?每一個(gè)用戶接口都是不一樣的.ASP.NET MVC團(tuán)隊(duì)不能猜對(duì)每個(gè)使用的input和label的布局的人想要什么樣的布局(layout).雖然每一個(gè)input節(jié)點(diǎn)都應(yīng)該有有個(gè)label.但是這個(gè)現(xiàn)存的helper方法可以創(chuàng)建那些不需要label的input節(jié)點(diǎn).相反的,我們可以使用ASP.NET MVC2中的特征的優(yōu)點(diǎn)--模版--去掌握一個(gè)更標(biāo)準(zhǔn)化的html的生成方式

 

 

3.2.4 使用強(qiáng)類型模版

     如果你現(xiàn)在已經(jīng)轉(zhuǎn)向用基于表現(xiàn)層的model形式的強(qiáng)類型視圖模式開(kāi)發(fā),那么你將要開(kāi)始發(fā)現(xiàn)越來(lái)越多的句式出現(xiàn)了。如果你的表現(xiàn)層model對(duì)象在表單里有個(gè)boolean屬性,你肯定會(huì)去使用checkbox在表單里面呈現(xiàn)。Email地址,password字段等等都是的。input節(jié)點(diǎn)沒(méi)有對(duì)應(yīng)的驗(yàn)證信息是很少出現(xiàn)的。

      除了使用HtmlHelper以外,在ASP.NET MVC2開(kāi)始出現(xiàn)的時(shí)候,templated helpers新的特性出現(xiàn)了,它被設(shè)計(jì)基于強(qiáng)類型視圖用來(lái)輔助設(shè)計(jì)生成html的一個(gè)技術(shù)。Templated helper可以為一個(gè)完整的model生成html或者為一個(gè)member生成html。

  

3.3.1 EditFor和DisplayFor 模版

    這兩個(gè)不同的模版集被分成了編輯(editor)和展現(xiàn)(display)模版。這個(gè)編輯和展現(xiàn)的模版有下面代碼生成

  雖然在使用模版,同樣效果用字符串方式的方法對(duì)弱類型的視圖不利,但是我們可以使用基于表達(dá)式的方法來(lái)在強(qiáng)類型視圖里面獲得優(yōu)勢(shì)(lambda表達(dá)式語(yǔ)法)。如果我們的model比較簡(jiǎn)單,我們可以使用ForModel系列的方法,它會(huì)重復(fù)遍歷model中的每一個(gè)成員(

member),然后生成html。

  在我們的修改密碼的頁(yè)面上布局比較簡(jiǎn)單,我們可以使用EditorForModel方法來(lái)生成一個(gè)用于編輯信息的表單

 

  ①我們?cè)贛odels/AccountModels.cs里面我們先添加一個(gè)類

   

這個(gè)代碼和LocalPasswordModel代碼一樣的,我們復(fù)制一下代碼改一下名字。

雖然已經(jīng)有了更改密碼的頁(yè)面了,但是這里我們只是練習(xí)一下EditorForModel的用法,還希望不用嫌麻煩

接下來(lái)我們?cè)贑ontroller/AccountController.cs用法

添加一個(gè)Action

  public ActionResult ChangePasswordPage() {
            ChangePasswordModel newPassword = new ChangePasswordModel();
            return View(newPassword);
        }
接下來(lái)我們右鍵該action名字,添加一個(gè)視圖。
視圖代碼如下:
@{
    ViewBag.Title = "ChangePasswordPage";
}
@using (Html.BeginForm())
{ 
  <div>
      <fieldset>
          <legend>用戶信息</legend>
          @Html.EditorForModel();
          <p><input type="submit" value="改變密碼"/></p>
      </fieldset>
 
  </div>  
}
 
 
接下來(lái)按F5運(yùn)行,可能首先你要登陸一下
 
登陸:
 
登陸成功后,我們先看一下原配的,點(diǎn)擊一下你的名字,進(jìn)入更改密碼界面
 
接下來(lái)我們修改一下地址欄
 
EditorForModel方法會(huì)在所在的view上循環(huán)對(duì)應(yīng)model中所有的member(成員),會(huì)為每個(gè)成員生成editor模版,我自己覺(jué)得這個(gè)也不怎么常用吧。文本框上面的文字,來(lái)自ChangePasswordModel類
 
 
但是有時(shí),我們不可能只要這么簡(jiǎn)單的輸出html,為了更靈活,比如說(shuō)我們調(diào)整布局,或者添加更多的html標(biāo)簽等等
接下來(lái)我們使用EditorFor模版
效果如下,發(fā)現(xiàn)只有含有驗(yàn)證功能的文本框
 
 
當(dāng)然,你把EditorFor改成Editor也行,只不過(guò)有的名稱你可能記不住,所以說(shuō)For系列的模版,例如EditorFor而不是Editor,所以正確性更高
代碼如下
 
 
3.3.2 內(nèi)置模版
    不出所料,ASP.NET MVC有一套自己的編輯和展示的模版,大致如下
    
 
 
除了Collection和Object模版,其他的模版都呈現(xiàn)的是唯一的值,Object模版循環(huán)訪問(wèn)ModelMetadata.Properties集合中的每一項(xiàng),每一項(xiàng)展現(xiàn)的時(shí)候都調(diào)用對(duì)應(yīng)的display模版.Collection模版循環(huán)訪問(wèn)model對(duì)象中的每一項(xiàng),并為列表中的每一項(xiàng)調(diào)用對(duì)應(yīng)的display模版顯示。
正如你預(yù)料到的,展示模版在瀏覽器中呈現(xiàn)為一個(gè)節(jié)點(diǎn),例如純文本或者一個(gè)錨標(biāo)簽,相反地,editor(編輯)模版展現(xiàn)的是表單中的節(jié)點(diǎn),默認(rèn)的編輯模版在表3.3都列出來(lái)了
 

3.3.3 查找模版

editor模版和display模版助手方法(helper methods)都是通過(guò)名字查找對(duì)應(yīng)的模版.模版的名字的值也是有來(lái)源的.模版助手方法根據(jù)這個(gè)名字,然后用明確的算法找到對(duì)應(yīng)的模版并呈現(xiàn)。一旦匹配找到了,就會(huì)立即去呈現(xiàn)內(nèi)容。模版助手方法在根據(jù)下一個(gè)模版名字查找之前,會(huì)根據(jù)明確的路徑查找模版。查找的路徑是EditorTemplates和DisplayTemplates文件夾。跟控制器找視圖有點(diǎn)像.如果一個(gè)助手方法在一個(gè)明確域(area)的視圖里面被使用了,被查找的文件夾可能是:
 
<Area>/<ControllerName>/EditorTemplates/<TemplateName>.cshtml(或者.vbhtml)<Area>/Shared/EditorTemplates/<TemplateName>.cshtml(或者.vbhtml)
 
如果模版不在這些文件夾里,或者視圖不在域里,這個(gè)默認(rèn)的視圖查詢地址就會(huì)被使用
 
<ControllerName>/EditorTemplates/<TemplateName>.cshtml(或者.vbhtml)Shared/EditorTemplates/<TemplateName>.cshtml(或者.vbhtml)
  •  
  • 關(guān)于模版的查找是遵循算法的
 
舉個(gè)例子:

我們現(xiàn)在要在更改密碼頁(yè)面上展現(xiàn)一個(gè)自定義的ChangePasswordModel模版。model我們已經(jīng)有了,現(xiàn)在我們只需要定義一個(gè)更model類型名字(ChangePasswordModel)一樣的模版就行了。文件放的路徑如下圖

左邊一個(gè),只給AccountController使用,右邊一個(gè),所有的控制器都可以使用,EditorTemplates文件夾是自己建立的

 
 
3.3.4 自定義模版(難)
 
總而言之,有兩種理由去創(chuàng)建一個(gè)自定義模版

■ 創(chuàng)建一個(gè)自定義模版 ■ 重寫現(xiàn)有的模版

 
首先我們看一下在控制器明確的視圖文件夾下的模版解決方案規(guī)則,因此我們能夠很明確的在Shared文件夾下重寫一個(gè)內(nèi)置的模版,然后我們?cè)谥貙懣刂破髅鞔_的視圖文件夾里。
解釋一下“控制器明確的視圖文件夾”:例如GuestController這個(gè)就是控制器明確了,名字是Guest,所以我們能找到對(duì)應(yīng)的視圖文件夾,例如 Views/Guest/…   這個(gè)最終的文件夾路徑就是  控制器明確的視圖文件夾
打個(gè)比方,你可能有一個(gè)應(yīng)用廣泛的模板,用于顯示的電子郵件地址.然后在一個(gè)域或者控制器模版的文件里提供一個(gè)模版。
在大多數(shù)情況下,模版跟創(chuàng)建一個(gè)類型是一樣的。ChangePasswordModel模版標(biāo)簽如下
 
創(chuàng)建一個(gè)新的Object.cshtml.里面用了EditorFor模版,每一個(gè)被P標(biāo)簽包裹。局部模版有什么好處?
首先,局部模版在視圖里面都是通過(guò)名稱找到的。避開(kāi)在視圖中明確指定哪一個(gè)模版被調(diào)用的需要,模版可以從model元數(shù)據(jù)信息中找到。此外模版能夠在ViewDataDirectory中獲得額外的信息,然而局部模版和其他的頁(yè)面是獲得不到的。這些信息在View.Data.ModelMetadata屬性中.只有在ASP.NET MVC中模版才有ModelMetadata屬性.在局部模版和視圖,這些屬性都為null
使用ModelMetadata屬性時(shí)候,你能夠獲得從model元數(shù)據(jù)提供器生成的所有元數(shù)據(jù)信息。這些包括關(guān)于model的model類型信息,屬性,和元數(shù)據(jù)。
Model類型信息包括的屬性都在表3.4列出來(lái)了
 
除了一些model類型信息之外,ModelMetadata也包含了其他的metadata,默認(rèn)的都是來(lái)自特性.如圖表3.5
 
在我們自定義模版中,我們研究一下這些model元數(shù)據(jù),然后去自定義HTML去呈現(xiàn)。除了在表3.4和3.5列出來(lái)的屬性之外,ModelMetadata對(duì)象暴露了一個(gè)IDictory<string,object>類型的AdditionValues屬性。這個(gè)屬性包含了一些來(lái)自自定義model元數(shù)據(jù)提供者的額外的元數(shù)據(jù)信息.舉個(gè)例子:如果你想展示一個(gè)必填的(required)字段,我們只需要在我們的自定義模版中檢測(cè)這個(gè)IsRequired屬性。比如說(shuō)我們要裝飾一下我們的實(shí)體中的一個(gè)DataType.DateTime數(shù)據(jù)類型的特性,我們可以用一個(gè)日期捕獲插件來(lái)自定義個(gè)模版來(lái)呈現(xiàn)時(shí)間。
實(shí)踐一下,我們可能要重寫一下現(xiàn)有的模版,因?yàn)檫@個(gè)現(xiàn)有的Object模版可能適合,可能不適合我們的需求。這個(gè)model的元數(shù)據(jù)不能包括任何樣式信息,所以自定義的樣式和其他的標(biāo)簽都是通過(guò)重寫內(nèi)置的模版完成的。但是很多網(wǎng)站都趨向于標(biāo)準(zhǔn)的通用的用戶接口布局,比如說(shuō)我們通常把一個(gè)label放在一個(gè)input上面用作標(biāo)記和提醒用戶,或者用一個(gè)*來(lái)標(biāo)記這個(gè)input是必須輸入內(nèi)容的。我們只需要重寫模版,就可以潛移默化地影響整個(gè)站點(diǎn)。

比如說(shuō),我們可能希望把label放在跟input放在同一行,而不是在一列后右對(duì)齊,為了達(dá)到這個(gè)目的,我們需要重寫現(xiàn)有的Object模版

①我們首先在 Views/Shared/下面建立一個(gè)EditorTemplates文件夾,添加一個(gè)Object.cshtml,代碼如下
@foreach (var prop in ViewData.ModelMetadata.Properties
                  .Where(pm => pm.ShowForEdit
                       && !ViewData.TemplateInfo.Visited(pm)))
{ 
    <div class="editor-field-container" style="clear:both">
        @if (!String.IsNullOrEmpty(
                    Html.Label(prop.PropertyName).ToHtmlString()))
        { 
            <div class="editor-label  float-left">
                @Html.Label(prop.PropertyName)                 
            </div> 
        }
        <div class="editor-field float-left">
            @Html.Editor(prop.PropertyName)
            @Html.ValidationMessage(prop.PropertyName, "*")
        </div>
        <div class="cleaner" style="clear:both"></div>
    </div> 
  
}

②接下來(lái)修改Views/Account/Login.cshtml代碼

@model GuestInfo.Models.LoginModel
 
@{
    ViewBag.Title = "登錄";
}
 
<hgroup class="title">
    <h1>@ViewBag.Title.</h1>
</hgroup>
 
<section id="loginForm">
<h2>使用本地帳戶登錄。</h2>
@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
 
    <fieldset>
        <legend>“登錄”表單</legend>
        @Html.EditorForModel()
 
        <input type="submit" value="登錄" />
    </fieldset>
    <p>
        @Html.ActionLink("Register", "Register") (如果你沒(méi)有帳戶)。
    </p>
}
</section>
 
<section class="social" id="socialLoginForm">
    <h2>使用其他服務(wù)登錄。</h2>
    @Html.Action("ExternalLoginsList", new { ReturnUrl = ViewBag.ReturnUrl })
</section>
 
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

按F5運(yùn)行效果,登陸頁(yè)面如下:

 

我們創(chuàng)建了一個(gè)foreach循環(huán),一層一層地遍歷了在編輯時(shí)以前應(yīng)該顯示的或者不應(yīng)該顯示的ModelMetadata.Properties屬性.展示一個(gè)label,editor模版,還有驗(yàn)證信息,把每一個(gè)屬性放在一個(gè)div標(biāo)簽里面.最后我們包括了一個(gè)cleaner div重置了浮動(dòng)樣式應(yīng)用于實(shí)現(xiàn)列布局.這個(gè)最終效果在圖3.5
在一個(gè)全局的模版中通過(guò)放一個(gè)普通的呈現(xiàn)邏輯,我們可以很容易的跨站點(diǎn)為我們的視圖,提供標(biāo)準(zhǔn)化display和editor布局.為了達(dá)需要自定義化的效果的域,我們要有選擇性的重寫或者提供一個(gè)新模版,通過(guò)在一個(gè)地方標(biāo)準(zhǔn)化和封裝我們的呈現(xiàn)內(nèi)容的邏輯,我們?cè)谝粋€(gè)地方編寫了很少的代碼就影響了整個(gè)站點(diǎn)(site),如果我們想要改變我們的時(shí)間插件,我們可以簡(jiǎn)單的寫一個(gè)data-time模版,就可以很容易改變我們的站點(diǎn),讓它呈現(xiàn)不同的內(nèi)容。

 

 

3.4 總結(jié)

MVC框架可以在視圖(頁(yè)面)里減少很多商業(yè)邏輯,不幸運(yùn)的是,視圖給我們帶來(lái)了很多必須掌握的復(fù)雜的東西,為了應(yīng)付這個(gè)復(fù)雜度和難點(diǎn),為了提高視圖和其他模塊的結(jié)合性,我們研究了怎樣使用強(qiáng)類型視圖和隔離開(kāi)的視圖model,隨著分離的視圖model的普遍增加,使用模版從這些視圖model中獲得元數(shù)據(jù)來(lái)呈現(xiàn)內(nèi)容的概念已經(jīng)成為可能。在分隔開(kāi)的視圖model中,在你的應(yīng)用程序中,我們還是要保持視圖和model是分離開(kāi)的理念。
 現(xiàn)在我們理解了視圖是怎么工作的了,下一章我們將探討一下控制器基礎(chǔ)
 
 
第二章代碼下載:http://download.csdn.net/download/yangyanghaoran/5207734

 額外贈(zèng)送:

臨時(shí)去除迅雷看看廣告的做法【原創(chuàng)】
①打開(kāi)資源管理器

           


②打開(kāi)迅雷看看,播放任意電影,緊接著會(huì)有廣告

          

    ③查看資源管理器,多了一個(gè)這個(gè)進(jìn)程 XLUEOPS.exe,我們只要在廣告播放的30秒內(nèi)手動(dòng) 關(guān)閉此進(jìn)程,就可以立即 去掉廣告,每次放廣告,迅雷看看都會(huì)加載此進(jìn)程

         

        ④右鍵單擊它,結(jié)束進(jìn)程,就可以臨時(shí)去掉廣告

其他方法:

    

如果你裝了360安全衛(wèi)士,直接點(diǎn)一鍵加速,就可以臨時(shí)去掉廣告

 

 

 


個(gè)人覺(jué)得3.3.4 自定義模版有點(diǎn)難,看不懂的也不用糾結(jié)我。這里只是視圖基礎(chǔ),具體的以后再講

 

關(guān)于ASP.NET MVC4 IN ACTION系列目錄地址已經(jīng)生成:點(diǎn)擊查看目錄

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
ASP.NET MVC 3 入門級(jí)常用設(shè)置、技巧和報(bào)錯(cuò)(持續(xù)更新)
ASP.NET MVC 視圖(四)
[ASP.NET MVC 小牛之路]03
MVC3教程之新手入門
成功mvc視圖向控制器傳值的3種方法
運(yùn)用Ext JS 4的MVC架構(gòu)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服