初學ASP.NET MVC學習筆記(九)-Templates

初學ASP.NET MVC學習筆記(九)-Templates

 

今天在研究MVC 2 的新功能Templates,不過由於太新,所以只有英文的文件可以看只好邊流眼淚邊看英文來學習新功能了。

mvc 2 新功能請參考保哥的文章:ASP.NET MVC 2 Preview 1 已經推出,新版功能搶先預覽

ASP.NET MVC 2 Templates  這個網站不錯有很完整的教學。

今天我也是照著這個網站來學習Templates

首先呢,當一個Model丟到View上,

例如我在Controller中隨便抓一筆資料


public ActionResult Index()
{
            MyDataContext db = new MyDataContext();

            return View(db.Regions.Where(p=>p.RegionNo_地區代號==15).FirstOrDefault());
}

加入一個View時,選擇強型別content為Detials,預設程式會產生這些Code


<fieldset>
        <legend>Fields</legend>
        
        <div class="display-label">RegionNo_地區代號</div>
        <div class="display-field"><%= Html.Encode(Model.RegionNo_地區代號) %></div>
        
        <div class="display-label">Region_縣市</div>
        <div class="display-field"><%= Html.Encode(Model.Region_縣市) %></div>
        
        <div class="display-label">Residence_鄉鎮市區</div>
        <div class="display-field"><%= Html.Encode(Model.Residence_鄉鎮市區) %><</div>
</fieldset>

也可以把上面這段全部刪掉,改用下面這樣來取代:

 


<fieldset>
        <legend>Fields</legend>
        <%=Html.DisplayForModel() %>
</fieldset>

出來的結果都一樣

27720ff72c934caba0a70c947dff6cb3

但是當這樣寫之後,就沒辦法在View直接更改樣式,這時候就要靠MetaData的Attribute的設定


[MetadataType(typeof(MetadataRegion))]
    public partial class Region
    {
        private class MetadataRegion
        {
            public int RegionNo_地區代號 { get; set; }

            public string Region_縣市 { get; set; }

            [DataType(DataType.Url)]
            public string Residence_鄉鎮市區 { get; set; }
        }
    }

內建有幾種template可以用,例如只要設定[DataType(DataType.XXX)]

就會顯示出預設的樣式,例如Url就是顯示為超連結,EmailAddress就是會加上mailto:

Html就是顯現Html的樣式,不過Html要注意的是顯示出來是未編碼的,所以有可能會被攻擊。

上面的例子是我隨便把鄉鎮市區的屬性設成Url的格式,所以顯現出來的時候會變成:

cd63aefca9fe4001add2454ad5071631 

就是超連結的樣式。

當不滿意或是不敷用的時候,也可以override這些預設的template

例如想要將超連結的底線拿掉,然後將字改成綠色(當然用CSS就可以簡單做到,這邊只是示範)

這邊示範的是DisplayTemplates,所以就在對應的資料夾下建一個DisplayTemplates資料夾

(或是可以放在Shared底下,他會照著

  • ~/Areas/AreaName/Views/ControllerName/DisplayTemplates/TemplateName.aspx & .ascx
  • ~/Areas/AreaName/Views/Shared/DisplayTemplates/TemplateName.aspx & .ascx
  • ~/Views/ControllerName/DisplayTemplates/TemplateName.aspx & .ascx
  • ~/Views/Shared/DisplayTemplates/TemplateName.aspx & .ascx

這樣的順序去尋找。)

然後在該資料夾底下建一個Url.ascx

(因為我要override的是Url,如果我要override的是Html就取名為Html.ascx)

7c3acec03fea41d0af51e4847a5df6df

建好之後在裡面加上幾行Code:


<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<a href="<%= Html.AttributeEncode(Model) %>" style="text-decoration:none;color:Green">
<%= Html.Encode(ViewData.TemplateInfo.FormattedModelValue) %></a>

第2行的後面我加了樣式,第三行的ViewData.TemplateInfo.FormattedModelValue在template裡

常常出現,說明請看洋文

The value of this field is either the properly formatted model value as a string (based on the format strings on ModelMetadata), or the original raw model value (if there is no format string specified).

如果不只是改一個欄位樣式,而想改全部的格式的話,可以加一個Object.ascx

 


<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
	<% if (Model == null) { %>
	    <%= ViewData.ModelMetadata.NullDisplayText %>
	<% } else if (ViewData.TemplateInfo.TemplateDepth > 1) { %>
	    <%= ViewData.ModelMetadata.SimpleDisplayText %>
	<% } else { %>
	    <table cellpadding="0" cellspacing="0" border="0">
	    <% foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForDisplay && !ViewData.TemplateInfo.Visited(pm))) { %>
	        <% if (prop.HideSurroundingHtml) { %>
	            <%= Html.Display(prop.PropertyName) %>
	        <% } else { %>
	            <tr>
	                <td>
	                    <div class="display-label" style="text-align: right;">
	                        <%= prop.GetDisplayName() %>
	                    </div>
	                </td>
	                <td>
	                    <div class="display-field">
	                        <%= Html.Display(prop.PropertyName) %>
	                    </div>
	                </td>
	            </tr>
	        <% } %>
	    <% } %>
	    </table>
	<% } %>

就可排列出自己想要的格式

72e4b6fcf7d94d11bfe2db482e251499

由於設定以及屬性太多,有興趣的請去看英文的說明吧。

接下來做一個只要是DateTime型態的屬性,在Edit的時候會自動出現jQuery的日曆選單

先簡單建一個Class

 


public class Member{
        public string Name{get;set;}
        public DateTime BirthDay { get; set; }
        public string Phone { get; set; }
    }

在Controller中new一個Member然後直接丟回View

 


 public ActionResult About()
        {
            Member m = new Member();
            return View(m);
        }

View裡面只寫<%=Html.DisplayForModel() %> 其他靠template產生

接著我要override DateTime這個template,所以我在Views/Home下建一個EditorTemplates資料夾

然後新增一個DateTime.ascx

307952f10eb44c7c8ddeb9601b87b3ba

在剛檔案中寫入:

 


<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%= Html.TextBox("", String.Format("{0:yyyy年MM月dd日}",ViewData.TemplateInfo.FormattedModelValue)) %>
<script type="text/javascript">
    $(function () {
        $(<%="'#"+ViewData.ModelMetadata.PropertyName+"'"%>).datepicker({
			showOn: 'button',
			buttonImage: '/Content/images/calendar.gif',
			buttonImageOnly: true,
            dateFormat:'yy年mm月dd日',
            changeYear: true
		});
    });
</script>

3-13行是我直接去 http://jqueryui.com/ 這邊抓的一個月曆套件,相關用法網站上有詳細說明。

執行的結果就會是:

f5ed9b023ec54aa8bd3cbfda829cd8c6

之後只要是DateTime的型態,在Edit的時候,就會有一個小月曆在旁邊。