2011年11月28日 星期一

ASP.NET+C# 如何取得 Request URL 的各個部分


我們在開發網頁應用程式,時常需要去解析網址(Request.Url)的每個片段,進行一些判斷。
例如說 "http://localhost:1897/News/Press/Content.aspx/123?id=1#toc",
我們想要取得網址裡第一層目錄的名字(News)用以判斷不同的頁面標題(Page Title)。

我看很多人都用字串的 IndexOf 方法與 Substring 方法:

Request.Url.PathAndQuery.Substring(1, Request.Url.PathAndQuery.IndexOf("/", 1)-1)

這實在太埋沒 .NET 的強大設計了,事實上在 Request 物件就已經提供很多方便的屬性(Property)
可供取得網址的片段。

底下這張表就是各種跟 Browser Request 的網址相關的屬性與用法:

網址:http://localhost:1897/News/Press/Content.aspx/123?id=1#toc
Request.ApplicationPath/
Request.PhysicalPathD:\Projects\Solution\web\News\Press\Content.aspx
System.IO.Path.GetDirectoryName(Request.PhysicalPath)D:\Projects\Solution\web\News\Press
Request.PhysicalApplicationPathD:\Projects\Solution\web\
System.IO.Path.GetFileName(Request.PhysicalPath)Content.aspx
Request.CurrentExecutionFilePath/News/Press/Content.aspx
Request.FilePath/News/Press/Content.aspx
Request.Path/News/Press/Content.aspx/123
Request.RawUrl/News/Press/Content.aspx/123?id=1
Request.Url.AbsolutePath/News/Press/Content.aspx/123
Request.Url.AbsoluteUrihttp://localhost:1897/News/Press/Content.aspx/123?id=1
Request.Url.Schemehttp
Request.Url.Hostlocalhost
Request.Url.Port1897
Request.Url.Authoritylocalhost:1897
Request.Url.LocalPath/News/Press/Content.aspx/123
Request.PathInfo/123
Request.Url.PathAndQuery/News/Press/Content.aspx/123?id=1
Request.Url.Query?id=1
Request.Url.Fragment 
Request.Url.Segments/
News/
Press/
Content.aspx/
123



所以當你看了這張表之後,你還會想用
 Request.Url.PathAndQuery.Substring(1, Request.Url.PathAndQuery.IndexOf("/", 1)-1) 這種寫法嗎?

用這樣寫 Request.Url.Segments[1].Replace("/", "") 不是又短又直覺嗎? ^_^

以下是產生以上表格的程式碼:
protected void Page_Load(object sender, EventArgs e)
{

    StringBuilder sb = new StringBuilder();

    sb.Append("<table cellpadding=3 cellspacing=0 border=1>");

    sb.Append("<tr><td colspan=2>");
    sb.Append("網址:http://localhost:1897/News/Press/Content.aspx/123?id=1#toc");
    sb.Append("</td></tr>");

    // Request.ApplicationPath
    sb.Append("<tr><td>");
    sb.Append("Request.ApplicationPath");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.ApplicationPath + "</b>");
    sb.Append("</td></tr>");

    // Request.PhysicalPath
    sb.Append("<tr><td>");
    sb.Append("Request.PhysicalPath");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.PhysicalPath + "</b>");
    sb.Append("</td></tr>");

    // System.IO.Path.GetDirectoryName(Request.PhysicalPath)
    sb.Append("<tr><td>");
    sb.Append("System.IO.Path.GetDirectoryName(Request.PhysicalPath)");
    sb.Append("</td><td>");
    sb.Append("<b>" + System.IO.Path.GetDirectoryName(Request.PhysicalPath) + "</b>");
    sb.Append("</td></tr>");

    // Request.PhysicalApplicationPath
    sb.Append("<tr><td>");
    sb.Append("Request.PhysicalApplicationPath");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.PhysicalApplicationPath + "</b>");
    sb.Append("</td></tr>");

    // System.IO.Path.GetFileName(Request.PhysicalPath)
    sb.Append("<tr><td>");
    sb.Append("System.IO.Path.GetFileName(Request.PhysicalPath)");
    sb.Append("</td><td>");
    sb.Append("<b>" + System.IO.Path.GetFileName(Request.PhysicalPath) + "</b>");
    sb.Append("</td></tr>");

    // Request.CurrentExecutionFilePath
    sb.Append("<tr><td>");
    sb.Append("Request.CurrentExecutionFilePath");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.CurrentExecutionFilePath + "</b>");
    sb.Append("</td></tr>");

    // Request.FilePath
    sb.Append("<tr><td>");
    sb.Append("Request.FilePath");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.FilePath + "</b>");
    sb.Append("</td></tr>");

    // Request.Path
    sb.Append("<tr><td>");
    sb.Append("Request.Path");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.Path + "</b>");
    sb.Append("</td></tr>");

    // Request.RawUrl
    sb.Append("<tr><td>");
    sb.Append("Request.RawUrl");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.RawUrl + "</b>");
    sb.Append("</td></tr>");

    // Request.Url.AbsolutePath
    sb.Append("<tr><td>");
    sb.Append("Request.Url.AbsolutePath");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.Url.AbsolutePath + "</b>");
    sb.Append("</td></tr>");

    // Request.Url.AbsoluteUri
    sb.Append("<tr><td>");
    sb.Append("Request.Url.AbsoluteUri");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.Url.AbsoluteUri + "</b>");
    sb.Append("</td></tr>");

    // Request.Url.Scheme
    sb.Append("<tr><td>");
    sb.Append("Request.Url.Scheme");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.Url.Scheme + "</b>");
    sb.Append("</td></tr>");

    // Request.Url.Host
    sb.Append("<tr><td>");
    sb.Append("Request.Url.Host");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.Url.Host + "</b>");
    sb.Append("</td></tr>");

    // Request.Url.Port
    sb.Append("<tr><td>");
    sb.Append("Request.Url.Port");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.Url.Port + "</b>");
    sb.Append("</td></tr>");

    // Request.Url.Authority
    sb.Append("<tr><td>");
    sb.Append("Request.Url.Authority");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.Url.Authority + "</b>");
    sb.Append("</td></tr>");

    // local Request.Url.LocalPath
    sb.Append("<tr><td>");
    sb.Append("Request.Url.LocalPath");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.Url.LocalPath + "</b>");
    sb.Append("</td></tr>");

    // Request.PathInfo
    sb.Append("<tr><td>");
    sb.Append("Request.PathInfo");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.PathInfo + "</b>");
    sb.Append("</td></tr>");

    // Request.Url.PathAndQuery
    sb.Append("<tr><td>");
    sb.Append("Request.Url.PathAndQuery");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.Url.PathAndQuery + "</b>");
    sb.Append("</td></tr>");

    // Request.Url.Query
    sb.Append("<tr><td>");
    sb.Append("Request.Url.Query");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.Url.Query + "</b>");
    sb.Append("</td></tr>");

    // Request.Url.Fragment
    // 原則上你應該無法從 Request.Url.Fragment 取得任何資料,因為通常 Browser 不會送出 #toc 這個部分
    sb.Append("<tr><td>");
    sb.Append("Request.Url.Fragment");
    sb.Append("</td><td>");
    sb.Append("<b>" + Request.Url.Fragment + "</b>");
    sb.Append("</td></tr>");

    // Request.Url.Segments
    sb.Append("<tr>");
    sb.Append("<td>");
    sb.Append("Request.Url.Segments");
    sb.Append("</td>");
    sb.Append("<td>");
    string[] segments = Request.Url.Segments;
    foreach (string s in segments)
    {
        sb.Append("<b>" + s + "</b>");
        sb.Append("<br/>");
    }
    sb.Append("</td>");
    sb.Append("</tr>");

    sb.Append("</table>");

    ltlTable.Text = sb.ToString();
}

注意事項:
當程式部署(Deploy)到 IIS 6 之後,假設你的網址是 http://localhost:1897/News/Press/Content.aspx/123? ,
IIS 不知為何會將問號 ( ? ) 給刪除掉,以致於 ASP.NET 使用 Request.Url.Query 是空字串!
如果你的程式有判斷到這部分時就要特別注意,因為照理說應該會抓到才對!
不知道是不是 IIS 6 的 Bug ?


節錄來源:http://blog.miniasp.com/post/2008/02/10/How-Do-I-Get-Paths-and-URL-fragments-from-the-HttpRequest-object.aspx


2011年11月27日 星期日

Crystal Report Support Pack 2 for Visual Studio 2010


Visual Studio 2010 沒有內建之前版本都有附贈的 Crystal Report 報表工具,因為 Crystal Report 被 SAP 公司收購。會用到的好友,請到 SAP 官網上下載安裝。

目前到 11/24 日出到 Support Pack 2 版本。免費下載點:http://www.sdn.sap.com/irj/boc/support?rid=/webcontent/uuid/d01fdad8-44e5-2d10-61ad-9d2d4158f3a8

我試用的經驗,要注意專案是 32bit 或 64bit,純 32bit 環境 Build and Debug 都不會有問題,若 OS 是 64bit 專案是 32bit ,則 Build 會成功但 Debug Run 會有錯誤訊息,不過將該專案 Publish 到 Setup Disk 後,拿到 32bit OS 下安裝執行會正常。

---
Welly Lin

2011年11月26日 星期六

ASP.NET+C# 取得目前執行程式的路徑


抓取 WinForm 應用程式所在的目錄可使用下面方法,此方法會回傳應用程式設定輸出目錄完整路徑。
1System.Windows.Forms.Application.StartupPath

抓取 Console 應用程式所在的目錄可使用下面方法。
1System.AppDomain.CurrentDomain.BaseDirectory;

抓取 ASP.NET 網頁程式,所在的目錄可用下面方法。
1Server.MapPath(".");

若是要包成 Library 呢? 以上皆適用。
1System.AppDomain.CurrentDomain.BaseDirectory;

補充 :
01protected void Page_Load(object sender, EventArgs e) {
02        //傳回傳遞給方法之虛擬路徑的完整實體路徑
03        //傳遞給 MapPath 方法的路徑必須是應用程式的相對路徑,而不是絕對路徑。
04        Response.Write("Server.MapPath : " + Server.MapPath("~") + "<br />");
05
06        //抓取 ASP.NET 網頁程式,所在的目錄
07        Response.Write("Server.MapPath : " + Server.MapPath(".") + "<br />");
08
09        //取得 asp.net 應用程式在伺服器上虛擬應用程式根路徑
10        Response.Write("Request.ApplicationPath : " + Request.ApplicationPath + "<br />");
11
12        //取得目前要求的虛擬路徑
13        Response.Write("Request.CurrentExecutionFilePath : " + Request.CurrentExecutionFilePath + "<br />");
14
15        //取得目前要求的虛擬路徑,與 CurrentExecutionFilePath 屬性不同,FilePath 並不會反映伺服器端的傳輸。
16        Response.Write("Request.FilePath : " + Request.FilePath + "<br />");
17
18        //取得目前要求的虛擬路徑
19        Response.Write("Request.Path : " + Request.Path + "<br />");
20
21        //取得目前執行應用程式之根目錄的實體檔案系統路徑
22        Response.Write("Request.PhysicalApplicationPath : " + Request.PhysicalApplicationPath + "<br />");
23
24        //取得與要求的 URL 對應之實體檔案系統路徑
25        Response.Write("Request.PhysicalPath : " + Request.PhysicalPath + "<br />");
26    }
輸出結果