2010年12月21日 星期二

MVC 與 HTML5

雖然MVC3 RC2已經發佈了(Announcing ASP.NET MVC 3 RC2),但是MVC本身對與HTML5的開發支援還是有待加強。好消息是在微軟的codeplex.com網站中,可下載在MVC中欲使用HTML5開發的輔助工具,名為MVC HTML 5 Toolkit。以下就實際舉一個MVC 2專案來說明如何使用這個HTML5的工具。


先在開發環境建立一個ASP.NET MVC 2 專案檔,如下圖:


使用System.Web.Mvc.Html5元件


我們可先下載微軟官方MVC HTML 5 Toolkit,然後將這個工具在開發環境中當作是一個参考物件(Add Reference)包含到專案檔中,但沒有下載基本上也是可以全手工撰寫HTML5的新式標籤,有Toolkit只是比較方便撰寫程式,如下圖:


引用完後,可看到System.Web.Mvc.Html5這個元件已經包含在我們專案檔中了,如下圖:


在web.config設定檔加上 <add namespace="System.Web.Mvc.Html5" /> 讓整個專案都可使用,如下:


   1:  </system.web>
   2:    <pages >
   3:      <namespaces>
   4:        <add namespace="System.Web.Mvc.Html5" />
   5:      </namespaces>
   6:    </pages>
   7:  </system.web>

使用HTML5的Email、Slider Bar 與 Tag mark等標籤


在\Views\Home\Index.aspx程式中輸入以下程式碼與HTML5的新標籤,我們在撰寫的過程中,可以更方便的使用剛才引入的元件(System.Web.Mvc.Html5),配合MVC的寫法(<%: Html.Html5TextFor(……) %>),完整式碼如下:


   1:  <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
   2:   Inherits="System.Web.Mvc.ViewPage" %>
   3:  <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent"
   4:   runat="server">
   5:  HTML 5 Demo  
   6:  </asp:Content>
   7:  <asp:Content ID="Content2" ContentPlaceHolderID="MainContent"
   8:   runat="server">
   9:      <h2><%: ViewData["Message"] %></h2>
  10:      <b>Demo 1 : Email Type</b><br />
  11:      <label for="email">
  12:          請輸入您的Email:</label>
  13:      <%: Html.Html5TextBox("userEmal", InputTypes.InputType.Email,
  14:          "horacelin@chinatrust.com.tw") %>
  15:      <p>---------------------------------------------------</p>
  16:      <b>Demo 2 : Slider Bar</b>
  17:      <p>
  18:          Total Recall Awesomness Gauge
  19:      </p>    
  20:      <%: Html.Html5Range(1, 50, 2, 25, null) %>
  21:      <p>---------------------------------------------------</p>
  22:      <b>Demo 3 : Tag mark</b>
  23:      <p>
  24:          Now we will Demo...        
  25:          <mark>HTML 5 &lt;mark&gt; Demo</mark>
  26:          let you know something!
  27:      </p>
  28:      <button type="submit">
  29:          Submit Form
  30:      </button>
  31:  </asp:Content>

以IE9 與 Chrome 來測試MVC+HTML5


接著我們也使用不同的瀏覽器來觀察,以下是Google Chrome瀏覽器執行MVC + HTML5撰寫的範例網頁後的結果,這三個新的HTML5標籤,全部都可顯示預期的效果,如下圖:


如果我們使用IE9執行我們這個範例網頁,則很不幸的,這3種新的HTML5剛好都不能支援,如下圖:


結語


HTML5 中包含了很多方便的新式標籤,雖然我們在VS 2010中看不到對HTML5的支援開發工具,但很快的VS 2010 SP1中已經可以支援HTML5的開發,且未來HTML5若一旦成為正式版本後,無論是傳統的Web Form或是MVC的方式,相信微軟應該很快推出新版本的開發工具來支援 .NET + HTML5的開發。


参考網址


HTML5

W3C組織HTML5網址
W3Schools HTML5學習資源網址
Mozilla組織HTML5資源網址
維基百科HTML 5
微軟IE9 Beta and HTML5 CSS3
Google HTML5展示與教學網站(Cool)

MVC 與 VS 2010 SP1

微軟ASP.NET MVC
微軟MVC Html5 ToolKit網址
MVC + HTML5
VS 2010 SP1 介紹

2010年12月19日 星期日

.NET 4 URL Routing

ASP.NET 4中,有一個新的URL Routing的功能,可讓我們很方便的自由設定我們想要的URL格式,例如:
http://yourWebSite/search.aspx?key=WPF7

透過URL Routing,網址列可變成

http://yourWebSite/search/WPF7


http://yourWebSite/employee.aspx?country=UK&city=London
透過URL Routing,網址列可變成

http://yourWebSite/employee/UK/London


然後利用URL Routing的機制,系統會自動對應與攜帶參數到指定的實際程式中去執行,以下就介紹5種URL Routing的使用方式與範例。

首先我們建立一個Web Application,並且在Site.Master中設計幾個選單,每一個選單點下去,就透過Global.asax.cs,分別對應出各種URL Routing的使用方式。整個範例結果看起來如下:




在Site.Master中我們先撰寫每個menu、URL與參數值


   1:  <asp:Menu ID="NavigationMenu" runat="server" >
   2:    <Items>
   3:        <asp:MenuItem NavigateUrl="~/" Text="Home"/>
   4:        <asp:MenuItem NavigateUrl="~/About" Text="About"/>
   5:        <asp:MenuItem NavigateUrl="~/product/" Text="Product"/>                        
   6:        <asp:MenuItem NavigateUrl="~/search/hello" Text="Search"/>
   7:        <asp:MenuItem NavigateUrl="~/users/MarkLin" Text="User"/>   
   8:        <asp:MenuItem NavigateUrl="~/employee/UK/London/HoraceLin"
   9:                                 Text="Employee"/>
  10:    </Items>
  11:  </asp:Menu>

在Global.asax.cs中,我們要引用using System.Web.Routing,並且在RegisterRoutes這個Method中,寫入下列程式,分別表示使用者瀏覽器端輸入的各種URL,我們這邊該如何對應到真實的程式中。


   1:   
   2:  void RegisterRoutes(RouteCollection routes)
   3:  {
   4:      RouteTable.Routes.MapPageRoute("HomeRoute", "Home",
   5:                    "~/Default.aspx");
   6:      RouteTable.Routes.MapPageRoute("AboutRoute", "About",
   7:                    "~/About.aspx");
   8:      RouteTable.Routes.MapPageRoute("ProductRoute", "product",
   9:                    "~/product.aspx");            
  10:      RouteTable.Routes.MapPageRoute("SearchRoute",
  11:                  "search/{searchterm}", "~/search.aspx");
  12:      RouteTable.Routes.MapPageRoute("UserRoute",
  13:                  "users/{username}", "~/users.aspx");
  14:      RouteTable.Routes.MapPageRoute("EmployeeRoute",
  15:                  "employee/{country}/{city}/{name}", 
  16:                  "~/employee.aspx");
  17:      RouteTable.Routes.MapPageRoute("LoginRoute", "Login",
  18:                    "~/Account/Login.aspx");
  19:  }

RouteTable.Routes.MapPageRoute()之內基本上帶有4個参數,為了說明,本範例只帶前3個参數:

RouteTable.Routes.MapPageRoute(
    路徑名稱,
    路徑URL格式,
    對應實體的程式URL,
    (option)是否應該驗證使用者是否已獲得授權可存取實體 URL)


1.URL Routing with no param.


我們按下範例中的「Home」、「About」、「Product」選單與右上角的「Login In」連結(因在最右邊,Cut圖沒有出現),URL分別為「http://website/Home」、「http://website/About」、「http://website/product」與「http://website/Login」,透過Global.asax.cs中URL Routing機制,分別對應實際程式「Default.aspx」、「About.aspx」、「About.aspx」、「product.aspx」與「/Account/Login.aspx」,如下圖所示點選單後的畫面(請注意網址列的URL):





2.URL Routing + parms. + Page.RouteData.Values[]


我們按下範例中的「Search」選單,如Site.Master程式所述,這裡假設帶一個参數值hello,所以URL:「http://website/search/hello」,透過Global.asax.ca中URL Routing Format:search/{searchterm},{searchterm}即為參數名稱,分別對應實際程式search.aspx,並在search.aspx.cs撰寫如下程式:


   1:  protected void Page_Load(object sender, EventArgs e)
   2:  {
   3:     Result.Text = Page.RouteData.Values["searchterm"].ToString();
   4:  }

我們使用Page.RouteData.Values["參數名稱"]來承接參數值,並顯示在網頁控制項label=Result上,如下圖(請注意網址列的URL):



3.URL Routing + parms. + RouteUrl:RouteName


我們按下範例中的「Search」選單後,在search.aspx網頁中也撰寫如下連結:


   1:  <asp:HyperLink ID="HyperLink1" runat="server" 
   2:      NavigateUrl="<%$RouteUrl:RouteName=SearchRoute,
   3:      searchterm=scott%>">
   4:      Demo Routing : Search for Scott
   5:  </asp:HyperLink> 

上述RouteName後面即利用在Global.asax.cs中之前已經寫好的路徑名稱SearchRoute,後面接searchterm這個参數與參數值scott:


   1:  RouteTable.Routes.MapPageRoute("SearchRoute",
   2:       "search/{searchterm}",
   3:       "~/search.aspx");


所以URL為「http://website/search/scott」,透過Global.asax.cs中URL Routing Format:search/{searchterm}對應實際程式search.aspx,並顯示在網頁控制項label=Result上,如下圖(請注意網址列的URL):



4.URL Routing + parms. + RouteValue


如同上小段,URL也是帶一個参數,只是這裡是用RouteValue的與法來承接參數值。我們按下範例中的「User」選單,如Site.Master程式所述,這裡假設帶一個参數值MarkLin,所以URL為「http://website/users/MarkLin」,透過Global.asax.cs中URL Routing Format:users/{username},{username}即為參數名稱,分別對應實際程式users.aspx如下程式:


   1:  <p><asp:Label ID="Result" runat="server" Text=
   2:       "<%$RouteValue:username%>" CssClass="msg"/>
   3:  </p>

我們使用 RouteValue:參數名稱 來承接參數值,並顯示在網頁控制項label=Result上,如下圖(請注意網址列的URL):



5.URL Routing + multi parms. + RouteValue


我們按下範例中的「Employee」選單,如Site.Master程式所述,這裡假設帶3個参數值UK、London與HoraceLin,所以URL:「http://website//employee/UK/London/HoraceLin」,透過Global.asax.cs中URL Routing Format:employee/{country}/{city}/{name},{country}{city}{name}即為參數名稱,分別對應實際程式employee.aspx,並在employee.aspx撰寫如下程式:


   1:  <h2>Employee Information</h2> 
   2:  <p>
   3:  Country : <asp:Label runat="server" Text=
   4:                "<%$RouteValue:country%>"
   5:                CssClass="msg1"/><br />
   6:  City     : <asp:Label runat="server" Text=
   7:               "<%$RouteValue:city%>"
   8:                CssClass="msg1"/><br />
   9:  Name     : <asp:Label runat="server" Text=
  10:               "<%$RouteValue:name%>"
  11:                CssClass="msg1"/>
  12:  </p>

我們使用 RouteValue:參數名稱 來承接參數值,並顯示在網頁如下圖(請注意網址列的URL):


2010年12月14日 星期二

EntityFramework.dll CTP 5 release

這邊公告一個消息,.NET最新使用Entity Framework方式(現在很多Entity Framework的書我看又要丟掉,然後重寫了)。


微軟會出一個EntityFramework.dll的元件版本,之後使用.NET C#程式的一般OO程式寫法,就可以直接套用EntityFramework的方式存取資料庫。不用像現在要先連好資料庫,然後去create 一個EntityFramework的*.edmx檔案。


目前這個EntityFramework.dll版本是CTP 5。可至下列微軟網址下載,當然可待正式版再拿來用。

Microsoft ADO.NET Entity Framework Feature Community Technology Preview 5


加入後專案檔會自動參照(reference)EntityFramework.dll這個元件到專案中(當然MVC專案檔也會有)。


使用基本範例可參考Scott Gu這位微軟高層所發表的文章:

Announcing Entity Framework Code First CTP5 Release


將陸續介紹實際使用範例。

2010年12月8日 星期三

jQuery Ajax Mvc Part 8 - jQuery UI Progress Bar + Json (以jQuery UI Progress Bar介面 + 取回Json型態資料)

在這個例子MVC的架構中,希望能夠套用jQuery .Ajax()的方式,透過透過POST方式呼叫給Controller中的Action,經過Action處理後(可能是查詢或存取後端資料庫處理元件),透過jQuery UI progress bar的介面方式,回應目前系統處理狀態在使用者所瀏覽的網頁上,最後顯示Action處理後的Json型態資料。


首先使用VS Web Developer 2010 Express建立一個ASP.NET MVC的專案。


首先得引用jQuery,這裡我們使用Google API的方式,當然也可以將jQuery的相關js檔案直接加入我們的專案檔中來使用。

   1:  <script type="text/javascript" src="https://ajax.googleapis.com
        /ajax/libs/jquery/1.4.3/jquery.min.js"></script>
   2:  <script type="text/javascript" src="https://ajax.googleapis.com
        /ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script>

我們在/Models內建立一個Product類別,如下:


   1:  public class Product
   2:  {
   3:      public string Name { get; set; }
   4:      public int Price { get; set; }
   5:  }

接著,我們在HomeController中,加上兩個Action,可看到我們為了拉長Action處理時間,特別加上sleep()方法以更明顯來觀察progress bar的變化,並且回應一個「處理完成」的字串訊息如下:

   1:  public ActionResult jQueryDemo8()
   2:  {
   3:      return View();
   4:  }
   5:   
   6:  public JsonResult jQueryJasonProgressBar()
   7:  {
   8:      for (int i = 0; i < 8; i++)
   9:      {
  10:          Thread.Sleep(800);
  11:      }
  12:      List<Product> list = new List<Product>();
  13:      list.Add(new Product { Name = "F001", Price = 1320 });
  14:      list.Add(new Product { Name = "F002", Price = 3301 });
  15:      list.Add(new Product { Name = "F003", Price = 2623 });
  16:      list.Add(new Product { Name = "F004", Price = 1320 });
  17:      list.Add(new Product { Name = "F005", Price = 3301 });
  18:      list.Add(new Product { Name = "F006", Price = 2623 });
  19:      return Json(list);
  20:  }

並且建立一個jQueryDemo8.aspx的View,然後加上jQuery的.ajax()語法,說明如下:
1.URL:這裡就是我們MVC架構中,我們要POST的/{Controller}/{Action},就是上面程式碼中的HomeController中的jQueryJasonProgressBar這個Action。
2.type:我們使用POST的方式。
3.async:true表示我們需要使用同步即時的方式取得Server回應。
4.data:{},就是我們要這個範例並沒有傳給jQueryJasonProgressBar這個Action任何參數。
5.datatype:"json",表示我們回傳回來的是json型態資料。
6.error:當有錯誤發生時,在id=errormsg 區段中顯示錯誤訊息。
7.success:若執行完畢,則讓progress bar顯示長度為100%,並已Json型態傳回與顯示資料至id=Results的<div>區塊內。




   1:  <h2>jQuery Ajax Mvc - jQuery UI Progress Bar</h2>
   2:  <p>使用jQuery UI 的progress bar效果+
   3:  取回Json資料型態(一個List->包含數個Product物件資料)</p>
   4:   
   5:  <script type="text/javascript" language="javascript">
   6:  $(document).ready(function () {
   7:      $("#progressbar").progressbar({ value: 0 });
   8:      $("#progressbar").hide();
   9:      $("#loadingMsg").hide();
  10:      $("#btnSubmit").click(function () {
  11:          $("#progressbar").show();
  12:          $("#loadingMsg").show();
  13:          //設定progress bar的顯示方式與速度
  14:          var intervalID = setInterval(updateProgress, 250);
  15:          $.ajax({
  16:              url: "/Home/jQueryJasonProgressBar",
  17:              type: "POST",
  18:              async: true,
  19:              data: {},
  20:              dataType: "json",                                    
  21:              //當有錯誤發生時,在errormsg <div>中顯示錯誤訊息
  22:              error: function (xhr, status, thrownError) {
  23:                  $("#errormsg").text(xhr.statusText);
  24:                  $("#errormsg").show();
  25:              },
  26:              //當處理成功時,關閉progerss bar與loading 訊息,
  27:              //並且顯示Action處理後之資料
  28:              success: function (data) {
  29:                  $("#progressbar").progressbar("value", 100);
  30:                  $("#progressbar").hide();
  31:                  var result = '';
  32:                  $.each(data, function (index, d) {
  33:                      if (d.Name != '') {
  34:                          result += "Name:" + d.Name + " | ";
  35:                          result += "Price:" + d.Price + "<br/>";
  36:                      }
  37:                  });
  38:                  $("#Results").html(result);
  39:                  clearInterval(intervalID);
  40:                  $("#loadingMsg").hide();
  41:              }
  42:          });
  43:          return false;
  44:      });
  45:  });
  46:   
  47:  function updateProgress() {
  48:      var value = $("#progressbar").progressbar("option", "value");
  49:      if (value < 100) {
  50:          $("#progressbar").progressbar("value", value + 1);
  51:      }
  52:  }         
  53:  </script>
  54:   
  55:  <div id="progressbar"></div>
  56:  <div id="loadingMsg">Loading....</div>
  57:  <div id="Results"></div><br />
  58:  <input type="button" id="btnSubmit" value="Submit" />
  59:  <div id="errormsg" style="color:Red;"></div>


我們就可以執行這個MVC專案,我們點選Demo8這個頁籤,如下圖:


然後按下Submit按鈕後,就看到隨著處理時間經過而顯示灰色bar由短變長的jQuery UI progress bar效果與loading中的訊息,如下圖:


處理完畢後,可看到以Ajax同步的方式即時回傳的資料顯示在網頁上。