ASP.NET(十)--第一個ASP.net MVC 項目和Razor語法

一、第一個ASP.net MVC 項目

  1. 項目的創建:講課使用VS2015,用VS2013也可以,新建項目→Visual C#→Web→【ASP.Net Web應用程序】 ,不要勾選【將Application Insights添加到項目】,然後【確定】。在下一步的界面中選中“Empty”(初學者不要用MVC的模板項目,會太亂),勾選【MVC】,不要勾選【Host in the cloud】。一定注意:上面圖標選“empty”,不要選“MVC”;下面勾選MVC,否則會生成很多沒用的代碼。
    在這裏插入圖片描述
  2. 控制器的建立、視圖的建立 :在Controllers文件夾下點右鍵→【添加】→【控制器】→選擇【MVC5控制器-空】,類的名字以Controller結尾,比如“TestController”,會自動在Views文件夾下創建一個Test文件夾(如果不新建就手動建,這個文件夾的名字必須是TestController去掉Controller),在Views/Test下新建視圖Index(和TestController的Index方法一致):添加→視圖
    在這裏插入圖片描述
    在這裏插入圖片描述
  3. 新建一個用來收集用戶參數的類:IndexReqModel(類名無所謂)包含Num1、Num2兩個屬性(只要不重名,大小寫都可以)。然後聲明一個IndexRespModel類用來給view傳遞數據顯示,有Num1、Num2、Result。也可以同一個類實現,但是這樣寫看起來比較清晰。
    在這裏插入圖片描述
  4. 在Index.cshtml如下編寫
    在這裏插入圖片描述
  5. 調試啓動後,瀏覽器訪問:http://localhost:57005/Test/Index
    畫圖分析執行過程、數據流動過程:當用戶訪問“/Test/Index?num1=1&num2=5”的時候,會找到Controllers下的TestController的Index方法去執行,把請求參數按照名字填充到Index方法的參數對象中(MVC引擎負責創建對象,給數據複製,並且進行類型的轉換),reutrn View(resp)就會找到Views下的和自己的“類名、方法名”相對應的Index.cshtml,然後把數據resp給到Index.cshtml去顯示。@model (要小寫) WebApplication2.Models.IndexRespModel表示傳遞過來的數據是IndexRespModel類型的,@Model(大寫開頭)指向傳遞過來的對象。
    cshtml模板就是簡化HTML的拼接的模板,最終還是生成html給瀏覽器顯示,不能直接訪問cshtml文件。

二、Razor語法:

  1. Razor語法非常簡單,@啓動的區域爲標準的C#代碼,其他部分是普通的html代碼。
  2. 用法:
    • @{string a=“abc”;}@a @{C#代碼塊}。有標籤就是html代碼
    • @Model
    • @Model.dog.Name
    • @if(),@foreach()等C#語句
  3. 下面的代碼是不行的,因爲純文字被視爲C#代碼:
   if(Model.IsOK)
   {
   啓用
   }

要使用“@:”前綴(不推薦),如下:

   if(Model.IsOK)
    {
    @:啓用
    }

如果要在代碼區塊中輸出大量文字,只要在代碼前後加上Html標籤即可

   if(Model.IsOK)
    {
    <span>啓用</span>
    }

razor會智能識別哪塊是C#,哪塊是HTML,HTML中想運行C#代碼就用@,想在C#中代碼中輸入HTML就寫“HTML標籤”。
但是如果由於樣式等原因不詳加上額外的標籤,那麼可以用標記,特殊的不會輸出到Html中。
4. 不要習慣性在@item後寫分號
5. Razor理解HTML標記語言的結構,當<li>標籤關閉的時候他也可以自動轉回代碼@foreach(var item in strs)
{<li>yes @item</li>}
6. Razor語法 :razor會自動識別哪塊是普通字符,哪塊是表達式,主要就是根據特殊符號來分辨(“識別到這裏是否能被當成一個合法的C#語句”)。不能這樣寫<a href="[email protected]">否則razor會認爲ashx是CourseId的一個屬性,應該加上()強制讓引擎把CourseId識別成一個單獨的語法<a href="Course(@CourseId).ashx">,不確定的地方就加個括號。通過VS中編輯器的代碼着色也可以分辨出來。
7. 如果不能自動提示,把頁面關掉再打開就行了。如果還不能自動提示,只要運行沒問題就行。cshtml文件中如果有警告甚至錯誤,只要運行沒問題就沒關係。
8. <span>[email protected]</span>,razor會自動識別出來是郵箱,所以razor不會把 @qq.com當成qq對象的com屬性。但是對於特殊的郵箱或者就是要顯示@,那麼可以使用@轉義@,也就是“@@”
9. <li>[email protected]</span>會把@item.Length識別成郵箱,因此用上()成爲:<li>item_@(item.Length)</span>
10. 易錯,要區分C#代碼和html代碼,下面是對的:style=‘display: @(message.IsHide ? “none” : “block”)’ 下面是錯誤的: style=“display: (@message.IsHide) ? none : block” 爲了避免C#中的字符串的"“和html的屬性值的”“衝突,建議如果html屬性中嵌入了C#代碼,那麼html的屬性的值用單引號。
11. Razor的@會自動把內容進行htmlencode輸出,避免了XSS攻擊,如果不想編碼輸出,那麼用@Html.Raw()
12. razor註釋使用@註釋內容@,不過誰會在cshtml中寫註釋???
13. (*)razor中調用泛型方法的時候,由於<>會被認爲是html轉回標記模式,因此要用圓括號括起來,比如@(Html.Test<String>),()永遠是很強大的。不過View中一般不會調用複雜的方法。
14. 如果cshtml中任何html標籤的屬性中以”~/"開頭,則會自動進行虛擬路徑的處理,當然一般是給<script>的src屬性、<link>的href屬性、<a>標籤的href屬性、<img>的src屬性用的。
15. html標籤的任何屬性的值如果是C#的值,那麼如果是bool類型的值,那麼如果值是false,則不會渲染這個屬性,如果值是true,則會渲染成“屬性名=屬性名”,比如:@{bool b1 = true; bool b2 = false;}
<aaa aa="/1.html" checked="@b1" ac="@b2">aaa</aaa>
16. 這個特性是爲<input type="radio/checkbox">的checked屬性和<select><option>的selected屬性使用的,這樣避免了進行三元運算符判斷。
17. cshtml是編譯生成一個動態的程序集;在cshtml中寫@this.GetType().Assembly.Location可以拿到編譯生成的程序集的dll文件的路徑,反編譯可以看到cshtml最終生成一個類,類中就是在拼接html;類是繼承自 WebViewPage,後續用的@Model、@Html等都是WebViewPage類的成員。
18. 儘可能維持View的簡單,不要在View中寫業務邏輯以及過去複雜的代碼

總結:

  • @就是C#,<aaa></aaa>就是html
  • 如果想讓被識別成html的當成C#那就用@()
  • 如果想讓被識別成C#的當成html,用<span>等標籤,如果不想生成額外的標籤,就用<text></text>
  • 如果不想對內容htmlencode顯示就用@Html.Raw
  • 屬性的值如果以"~/"開頭會進行虛擬路徑處理
  • 屬性值如果是bool類型,如果是false就不輸出這個屬性,如果true就輸出“屬性名=屬性名”<input type="checkbox" checked="@b1"/>

知識點補充

dynamic是C#中提供的一個語法,可以實現像JavaScript一樣的動態語言,可以到運行的時候再去發現屬性的值或者調用方法。
dynamic p = new Person();
p.Name = “InLett.com”;
p.Hello();
這樣即使沒有成員:p.Age=3;編譯也不報錯,只有運行的時候才報錯。
dynamic的好處是靈活,壞處是不容易在開發時候發現錯誤、而且性能低(反射看看)。
如果dynamic指向System.Dynamic.ExpandoObject()對象,這樣可以給對象動態賦值屬性(不能指向方法):

dynamic p = new System.Dynamic.ExpandoObject();
p.Name = "InLett.com";
p.Age = 10;
Console.WriteLine(p.Name+","+p.Age);

var類型推斷

var i=3;
var s="abc";

編譯器會根據右邊的類型推斷出來var是什麼類型,反編譯一下。
var和dynamic的區別:var是在編譯的時候確定,dynamic是運行的時候動態確定的;var變量不能指向其他類型的,dynamic可以。

匿名類型
匿名類型是C#中提供的一個新語法:var p = new{Age=15,Name=“InLett.com”};這是創建一個匿名類的對象,這個類沒有名字。反編譯看一下(IL模式下看)編譯器生成了一個類,這個類是internal(IL中是private)、屬性是隻讀的、初始值是通過構造函數傳遞。
因爲匿名類型的屬性是隻讀的,所以匿名類型的屬性是無法賦值;因爲匿名類型是internal,所以無法跨程序集訪問其成員。

三、 Controller給View傳遞數據的方式

ViewData

以ViewData[“name”]=“ylt”;string s=(string)ViewData[“name”]這樣鍵值對的方式進行數據傳送。

ViewBag

ViewBag是dynamic類型的參數,是對ViewData一個動態類型封裝,用起來更方便,和ViewData共同操作一個數據。ViewBag.name=""; @ViewBag.name。用ViewBag傳遞數據非常方便,但是因爲ASP.Net MVC中的“Html輔助類”等對於ViewBag有一些特殊約定,一不小心就跳坑了(https://www.cnblogs.com/webapi/p/5669035.html),所以儘量不要用ViewBag,而是使用Model,雖然會麻煩“越麻煩工資越高”

Model

可以在Controller中通過return View(model)賦值,然後在cshtml中通過Model屬性來訪問這個對象;
如果在cshtml中通過“@model 類型”(注意model小寫)指定類型,則cshtml中的Model就是指定的強類型的,這樣的cshtml叫“強類型視圖”;如果沒有指定“@model 類型”, 則cshtml中的Model就是dynamic。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章