天天看點

一起談.NET技術,ASP.NET MVC 2示例Tailspin Travel UI層分析

  Tailspin Travel設計的技術比較多,今天我們來看看界面(UI)上的技術,在UI層上來說主要采用的技術是ASP.NET MVC2和ASP.NET DynamicData架構。從功能上來分為向普通使用者提供的前台頁面和管理者使用的背景界面,前台頁面主要實作的是旅遊活動日程安排,航班,酒店,租車這幾部分采用的ASP.NET MVC 2技術,管理者用的背景管理頁面使用的是ASP.NET DynamicData開發的,這兩種技術在網站裡的應用有示範作用,對于管理者使用的背景的通路量不可能很大,網站的主要流量是普通使用者使用的前台頁面,組合使用這兩個架構,可以加快網站的開發。

  組合這兩種技術,就會碰到一些的問題,第一個問題就是ASP.NET 動态資料(Dynamic Data )預設情況下,動态資料放在web應用的動态資料目錄(DynamicData)裡,該目錄建立在根目錄處。你的應用需要移動的不同的位置。 在Tailspin Travel裡面是“admin”目錄,動态資料就在這個目錄下,然後在Globa.asax.cs檔案裡

var metaModel = new MetaModel();

metaModel.RegisterContext(contextFactory, new ContextConfiguration { ScaffoldAllTables =

true });

metaModel.DynamicDataFolderVirtualPath = "~/Admin/DynamicData/";

  改變admin/Dynamicdata 下檔案的内容的引用到新的路徑((~/admin/Dynamicdata)

例如:

A、修改List.aspx和ListDetails.aspx 的注冊指令的src屬性。

B、修改 List.aspx 和母版頁的img 的src屬性。

C、任何自定義的必須使用新路徑的内容。

  下面我們來具體分析前台和管理背景:

  ASP.NET 動态資料在進行建立和更新資料時還會對所錄入的資料進行驗證,這種驗證既發生在用戶端也發生在伺服器端。

必填字段驗證。如果字段不允許為 NULL,則錄入時必須錄入資料。不過這裡還有待改進,不允許為 NULL,也就成了不允許零長度字元串,而實際應用中 NULL 和零長度字元串是兩回事。縱然不夠完美,也已經為我們減輕不少工作量了。

長度驗證。如果字段類型為 nvarchar(10),那麼就不允許超過 10 個字元;如果字段類型不是 nvarchar(10),而是 varchar(10),此時六個漢字也會通過驗證,隻是無法入庫罷了,會傳回錯誤。

類型驗證。比如字段是日期類型,則隻允許錄入日期。

  ASP.NET 動态資料具有自動格式功能:比如 bit 類型的字段顯示為一個多選框,而辨別字段不會在插入資料時顯示出來。

  ASP.NET 動态資料還具有自動識别表關聯的功能:比如産品表與産品類别表進行了關聯,那麼我們在錄入産品資料的時候,ASP.NET 動态資料會自動以下拉清單的形式顯示産品類别。此功能非常不錯。

  在網站或者應用程式模闆中有兩個Dynamic Data模闆,一個是 "Dynamic Data實體模闆(Dynamic Data Entities )"它是使用ADO.net Entity作為資料模型的,另一個是 "Dynamic Data 模闆",他是使用LINQ TO SQL 來作為資料模型。Tailspin Travel 是以Entity Framework作為資料模型的。

  Dynamic Data也使用了Routing:

routes.Add(new DynamicDataRoute("Admin/{table}/{action}")

{

Constraints = new RouteValueDictionary(new { action = "List|Edit|Details|

Insert" }),

Model = metaModel

});

  routes.Add 的參數為一個 DynamicDataRoute 對象,而該 DynamicDataRoute 對象有一個參數為 "Admin/{table}/{action}.aspx",另外還為該對象指定了兩個屬性值 Constraints 和 Model。把一個繼承自Route的DynamicDataRoute添加到Routing規則表中。

  Constraints = new RouteValueDictionary(new { action = "List|Details|Edit|Insert" }) 這句表示限制,這裡表示 action 隻能是 List、Details、Edit、Insert 中的一個。

  可以看出,這四個Aciton是對應着DynamicData/PageTemplates檔案夾中的四個頁面檔案。在那檔案夾中還有一個ListDetails.aspx頁面檔案,是用于"合并頁模式",就是所有的操作都會在一頁中完成。Tailspin Travel并沒有啟用這個功能。DynamicData 檔案夾的名稱都是“DynamicData”。

  上面的 {table}、{action} 可不可以改成我們自己想要的名字呢?

  不行的,我們可以看到,上面使用的是 DynamicDataRoute 類,而不是 Route 類,DynamicDataRoute 繼承于 Route,Table 和 Action 屬性是 DynamicDataRoute 特有的。

  DynamicData/Content/GridViewPager.ascx 分頁控件。

  DynamicData/Content/FilterUserControl.ascx 在顯示表中的資料時,該控件顯示在表頭,用以過濾表中的内容,比如可以隻清單産品目錄為“實用工具”的産品。

  DynamicData/CustomPages 檔案夾。自定義網頁模闆檔案夾,可用以替換 DynamicData/PageTemplates 檔案夾中的預設模闆。

  DynamicData/FieldTemplates 檔案夾。包含各種類型的字段在檢視和建立、編輯時所呈現的控件。

  DynamicData/PageTemplates 檔案夾。包含在進行檢視、編輯時的頁面模闆。

  Dynamic Data還有一個快速開發的基礎是腳手架,腳手架是一種機制,通過腳手架,我們不必再為每一個表的增加、檢視、修改做不同的頁面,因為腳手架會自動生成這些頁面。Tailspin Travel對所有表都啟用腳手架,對所有表啟用腳手架表示公開了整個資料模型:

  metaModel.RegisterContext(contextFactory, new ContextConfiguration { ScaffoldAllTables = true });

  還可以對特定表啟用腳手架功能,這時就要将上面的ScaffoldAllTables = false,然後給模型類打标簽[System.ComponentModel.DataAnnotations.ScaffoldTable(true)]

  自動生成的網站需要我們調整的頁面,需要建立自定義的頁面可以把它放在DynamicData/CustomPages 檔案夾,在 DynamicData/CustomPages/ 下建立一個檔案夾,名稱為 FlightBookings,這個名稱一定要與 Tailspin.edmx中的相應表的分部類名稱一樣。然後将 DynamicData/PageTemplates/ 下的檔案複制到 DynamicData/CustomPages/FlightBookings/。

  更改新模闆檔案中的類名。

  比如将類名稱 List 改為 DynamicDataTest.FlightBookingsList。

  使用DisplayName更改界面的顯示,DisplayName 隻能用于類、方法、屬性、索引、事件

[MetadataType(typeof(CarRentalMetadata))]

public partial class CarRental

[ScaffoldTable(false)]

private class CarRentalMetadata

[DisplayName("Pick up")]

public object RentalStart { get; set; }

[DisplayName("Return")]

public object RentalEnd { get; set; }

[DisplayName("Pick up Place")]

[Required(ErrorMessage = "Please specify where you prefer to pickup the vehicle.

")]

public object PickupPlaceId { get; set; }

[DisplayName("Return place")]

[Required(ErrorMessage = "Please specify where you prefer to return the vehicle.

public object ReturnPlaceId { get; set; }

[DisplayName("Vehicle")]

[Required(ErrorMessage = "Please specify the vehicle type.")]

public object VehicleTypeId { get; set; }

}

  還可以用 UIHint,DataType 改變字段模闆

[MetadataType(typeof(FlightMetadata))]

public partial class Flight

public Flight()

this.Id = Guid.NewGuid();

[DisplayName("Flights")]

private class FlightMetadata

[ScaffoldColumn(false)]

public object Id { get; set; }

[Required]

public object AirplaneType { get; set; }

[UIHint("Time")]

public object DepartureTime { get; set; }

[DataType(DataType.Time)]

public object ArrivalTime { get; set; }

[DisplayName("Departure Airport")]

public object DepartureAirport { get; set; }

[DisplayName("Arrival Airport")]

public object ArrivalAirport { get; set; }

  DynamicData非常的靈活,Tailspin Travel用來對付管理背景的開發方面具有非常高的效率,在前台使用MVC2保證性能,在UI界面的開發方面非常值得借鑒的一種模式。

繼續閱讀