FileUpload中MIME

以下為MSDN中的MIME

Known MIME Types

text/richtext
text/html
audio/x-aiff
audio/basic
audio/wav
image/gif
image/jpeg
image/pjpeg
image/tiff
image/x-png
image/x-xbitmap
image/bmp
image/x-jg
image/x-emf
image/x-wmf
video/avi
video/mpeg
application/postscript
application/base64
application/macbinhex40
application/pdf
application/x-compressed
application/x-zip-compressed
application/x-gzip-compressed
application/java
application/x-msdownload

MIME常用在檔案上傳(FileUpload控制項),我們需要判斷檔案是否是我們要的類型,例如,我們希望使用者只能上傳zip檔:

IF FileUpload1.HasFile Then
  try
    IF FileUpload1.PostedFile.ContentType = "application/x-zip-compressed" Then
    'Code
    End IF
  '...
End IF

或是在傳送Mail(System.Net)時的附加檔案,總不希望使用者亂上傳資料檔案,所以就需要MIME來判斷,總之如果你需要資料使用者上傳了什麼東東,就需要使用MIME就對了。

參考:

ASP.NET控制Meta Tags

你或許使用過ASP.NET的Page.Title來修改網頁的標題,但你有沒有試過使用ASP.NET來修改Meta,你或許會說,那還不簡單,使用Page.Meta就好了,嗯!你打打看。

其實沒有那怎難,在ASP.NET中,除了控制項,我們還可以把一般的HTML轉換為HTML控制項,在ASP.NET中每一個HTML控制項都有對應的類別,例如,在Visual Studio中打「Dim meta As New html」你就可以看到所以html對應的類別,如HtmlAnchor對應的就是<a>。

但如果我們想在程式碼中操控這些HTML,那就先必須把這些HTML轉換為ASP.NET的控制項,轉換的過程異常簡單,只需要在HTML Tags裡加上「runat="server"」屬性馬上就能將HTML轉換為ASP.NET的控制項。就我們的需求,我想要操控Meta所以我幫Meta加上兩個屬性:

<meta id="metaName" runat="server" />

這樣就馬上讓meta成為ASP.NET的控制項,而id是為了讓我們可以在程式碼中進行設定。

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        metaName.Attributes("name") = "author"
        metaName.Attributes("Content") = "Bruce"
    End Sub

這樣讓meta可進行程式碼操作後,就可以進行許多事,例如我們的動態頁面裡的meta可以與資料庫互動,動態產生meta,來進行簡易meta的SEO動作。

一樣的原理,可以用於其他HTML中,重點只有在「runat="server"」,把HTML轉換為HTML控制項,成為控制項後,ASP.NET才能進行程式碼的操作。

使用Calendar控制項+jQuery實作DatePicker

我們在讓使用者輸入資料時,常有機會需要讓使用者選擇日期,所以而這種選擇日期的功能我們稱「Date Picker」,你上網搜尋,可以找到一大堆資源,但我想要使用ASP.NET裡的Calendar加jQuery來實作看看,動手做,樂趣無窮。

做法很簡單,我們先新增一default.aspx網頁,然後在網頁上放上一個TextBox及一個<img>,TextBox是讓使用者選擇完日期後,把日期放入TextBox之中,而<img>是顯示及隱藏Calendar控制項。

Default.aspx

<form id="form1" runat="server">
<div>
<asp:label associatedcontrolid="tbxDate" id="lblBirthday" runat="server" text="生日:">
        <asp:textbox id="tbxDate" runat="server">
        <img alt="選擇日期" id="ibnt" src="Calendar.png" />
</div>
<asp:calendar backcolor="White" bordercolor="#999999" cellpadding="4" daynameformat="Shortest" font-names="Verdana" font-size="8pt" forecolor="Black" height="180px" id="cal" runat="server" width="200px">
            <selecteddaystyle backcolor="#666666" font-bold="True" forecolor="White">
            <selectorstyle backcolor="#CCCCCC">
            <weekenddaystyle backcolor="#FFFFCC">
            <todaydaystyle backcolor="#CCCCCC" forecolor="Black">
            <othermonthdaystyle forecolor="#808080">
            <nextprevstyle verticalalign="Bottom">
            <dayheaderstyle backcolor="#CCCCCC" font-bold="True" font-size="7pt">
            <titlestyle backcolor="#999999" bordercolor="Black" font-bold="True">  </titlestyle></dayheaderstyle></nextprevstyle></othermonthdaystyle></todaydaystyle></weekenddaystyle></selectorstyle></selecteddaystyle></asp:calendar>
</form>

我們先在Defuault.asp.vb中處理ASP.NET的相關事件。

Defuault.asp.vb

  Protected Sub cal_DayRender(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DayRenderEventArgs) Handles cal.DayRender
        '生日不會大於今天,所以把大於今天的日期選取功能取消
        If e.Day.Date > DateTime.Now Then
            e.Day.IsSelectable = False
        End If
    End Sub

    Protected Sub cal_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cal.SelectionChanged
        Me.tbxDate.Text = Me.cal.SelectedDate.ToShortDateString
    End Sub

最後就是處理Calendar顯示及隱藏的jQuery:

jQuery - position

$(function() {
    //先隱藏Calendar
    $("#cal").hide();
    //<img>的click事件
    $("#ibnt").click(function() {
        var p = $("#ibnt");
        //可使用position或offset來取得<img>的top及left座標
        //var position = p.position();
        //$("#cal").css({ "position": "relative", "top": position.top, "left": position.left });
        var offset = p.offset();
        //設定相對位置
        $("#cal").css({ "position": "relative", "top": offset.top, "left": offset.left });
        $("#cal").toggle();
    });

    //讓TextBox也能有<img>一樣的效果
    $("#tbxDate").click(function() {
        var p = $("#tbxDate");
        var position = p.position();
        $("#cal").css({ "position": "relative", "top": position.top, "left": position.left });
        //var offset = p.offset();
        //$("#cal").css({ "position": "relative", "top": offset.top, "left": offset.left });
        $("#cal").toggle();
    });
 });

簡單吧,不過由於我們是使用ASP.NET的Calendar控制項,所以在點選時,會產生Postback,才有辦法把值寫入TextBox中,不像一般純JavaScript那樣單純,把值直接寫入TextBox中。控制項有控制項的好處,或許我們還能用CallBack來改寫,或使用Ajax實作來減少Postback,但我的重點是在jQuery,簡單又實用。

當業績與良心對上時

我的Focus已經過保固有一段時間了,因為習慣,雖然有認識保養廠的朋友,但我還是都回原廠保養。但近來我的Focus出現冷車異音的問題,但發生的頻率還不到100%,所以每次回原廠保養也沒查出什麼所以然?要嘛就不出聲,要嘛就咻咻咻的叫。

但這都不是問題,一般的保養是沒有什麼問題,但最近幾次進廠,都會有意外出現,我所謂的意外就是會發生:「先生,我們保養的過程發現你的愛車xxx有問題,這可能會有安全性上的問題,請問你是否要做更換?」

通常我們又不懂這些專有名詞,懂的只是皮毛,又聽到「安全性」上的問題,通常都會花錢了事,不過幾次下來,總覺得不對,而且每次都是壞那種我認為很奇怪的地方,例如有一次,Ford跟我說我Focus有一隻避振器漏油,問我是否要更換?我心想,我的Focus大多只跑高速公路,我們台灣的高速公路能「振」到Focus避振器漏油,也太不容易了吧,原本我是不想換,但剛好假日又要回宜蘭,心想,又是長途、又是安全性問題,而且重點是,我現在車上有寶寶,花錢了事吧。

重要的是,Ford每次這種「換東西的問題」產生時,你要換也可以,不換也可以,不換的話Ford是不會也不會跟你說什麼,好像出事也不關他們的事一樣,這樣的態度讓我有了疑心。照理說,如果真的會影響到安全(因為可能會死人),說什麼也要跟顧客解譯清楚,就算不在原廠維修,也要提醒顧客這個問題一定要去處理好,不要去影響到行車安全。

所以這一次送去保養後,真的電話又來了,又說我xxx有問題,是否要更換零件。這一次我就直接說不用了。我將車開回來了直接去找我保養廠的朋友,請他幫我看原廠說的那個問題,第二天我朋友打電話來,說原廠在放屁,他們要做業績,你不用理他們。

我說,做業績是什麼意思?我朋友說,你的零件根本沒問題。朋友還說,他學弟就在Ford原廠,他學弟跟他說,Ford原廠會要求業績,一台車進廠,沒花到5000以上他們會被「釘」,而且每個月還有60萬的業績要求,所以像我們這些過保的車,就是他們下手的目標。反正我們什麼也不懂,隨便唬唬可以達到要求了。

我朋友的解譯跟我的想法match,這樣的說法,請各位去求證,我也只是聽說,但我是相信的那一個。如果有問題,還是到現場請師博說明給你看,他們知道你是會到現場看的人,或許比較不敢這用電話唬人。

即時先行編譯(in-place precompilation)

我們都知道,在ASP.NET中,第一次被瀏覽的網頁會比較慢才會做出反應,原因是第一次被瀏覽的網頁需要complier,第二次就不用再complier,但如果我們想一開始就把全部的網頁都complier好,那可以使用即時先行編譯(in-place precomplation)技術。

如果網站剛上線,或Server維護重開機,可以使用這個方便的小工具,幫我們先把全部的網頁「點一遍」,也因為每一頁都被點過了,也代表每一頁都被complier過了,所以第一位進來的仁兄,不用等那麼久。

通常使用下面範例二即可。

C:\Windows\Microsoft.NET\Framework\v2.0.50727>aspnet_compiler.exe /?

先行編譯 ASP.NET 應用程式的公用程式
Copyright (C) Microsoft Corporation. All rights reserved.

使用方式:
aspnet_compiler [-?] [-m metabasePath | -v virtualPath [-p physicalDir]]
                [[-u] [-f] [-d] [-fixednames] targetDir] [-c]
                [[-keyfile file | -keycontainer container]
                     [-aptca] [-delaySign]]
                [-errorstack]

-?            列印這段說明文字。
-m            應用程式的完整 IIS Metabase 路徑。這個參數不能和 -v 或 -p 參數結合。
-v            要編譯的應用程式的虛擬路徑 (例如 "/MyApp")。如果已指定 -p,就會使用實體路徑尋找應用程式,否則會使用 IIS Me
tabase,並假設應用程式位於預設網站 (在
              "/LM/W3SVC/1/Root" 下)。這個參數不能和 -m 參數結合。
-p            要編譯的應用程式的實體路徑。如果遺漏 -p,就會使用 IIS Metabase 尋找應用程式。這個參數必須和 -v 結合。
-u            如果已指定這個路徑,就可以更新先行編譯的應用程式。
-f            如果目標目錄已存在則覆寫。現有的內容將遺失。
-d            如果已指定,會在編譯時發出偵錯資訊。
targetDir     編譯應用程式的實體路徑。如果未指定這個路徑,則會就地先行編譯應用程式。
-c            如果已指定,先行編譯的應用程式便會完整重建。任何之前編譯過的元件都會重新編譯。已指定 targetDir 時,永遠啟
用此選項。
-keyfile      強式名稱金鑰檔的實體路徑。
-keycontainer 指定強式名稱金鑰容器。
-aptca        如果已指定,強式名稱的組件將會允許部分信任的呼叫端。
-delaysign    如果已指定,建立時組件不會完整簽署。
-fixednames   如果已指定,編譯的組件將會獲得固定的名稱。
-nologo       隱藏編譯器著作權訊息。
-errorstack   顯示可協助進行特定條件偵錯的額外偵錯資訊。

範例:

下列兩個命令功能相同,而且都倚賴 IIS Metabase。編譯完成的應用程式會部署到 c:\MyTarget:

    aspnet_compiler -m /LM/W3SVC/1/Root/MyApp c:\MyTarget
    aspnet_compiler -v /MyApp c:\MyTarget



下列命令會就地編譯應用程式 /MyApp。如此一來,當 HTTP 要求傳送至這個應用程式時,就不再需要進行編譯:

    aspnet_compiler -v /MyApp



下列命令「不」倚賴 IIS Metabase,因為它會明確指定應用程式的實體來源目錄:

    aspnet_compiler -v /MyApp -p c:\myapp c:\MyTarget