2008年8月13日 星期三

微軟 Visual Studio.NET 2003 的主流支援到 2008/10/14

提醒一下。由於微軟的 mainstream support 策略,使用Visual Studio.NET 2003 的主流支援到 2008/10/14,見這裡。

也就是說,除非你自己出錢請微軟修改,否則 Visual Studio.NET 2003 不會再新增功能了。

建議開發新專案時,請使用 Visual Studio 2008,至少主流支援可到 2013 年。

Visual Studio 2005 也可以到 2011年

2008年8月12日 星期二

Sql Server Management Studio 2008 的 intellisense 不見了?

原本使用 CTP, RCO 時,Sql Server Management Studio 2008 的 intellisense 非常的好用。但我發現,正式版的 SSMS 不能連到2000, 2005 上了!! 這是真的。

When IntelliSense Is Unavailable. 上有一這麼一段 Intellisense is only available when the Database Engine Query Editor is connected to an instance of the SQL Server 2008 Database Engine.

MS 也真的好樣的!

Visual Studio 2008 sp1 and .NET Framework 3.5 sp1 final release

終於出來了。見 http://blogs.msdn.com/charlie/archive/2008/08/11/released-visual-studio-service-pack-1-net-3-5-service-pack-1.aspx 

因為,安裝 SQL Server 2008的client tool 時失敗了。原因是我的開發電腦上安裝的 Visual Studio 2008 尚未升級成 sp1。不讓我安裝。
當時就知道沒差幾天 Visual Studio 2008 就會出 sp1,否則會影響多少 developer 啊。

2008年8月8日 星期五

原來,DataGridView(WinForm) 與 GridView(Asp.net) 是如此的不同

一直都在實作 asp.net,很少寫 window form 的程式。
現在才發現,這兩個是如此的不同。

在 Asp.Net 的 GridView,簡單的程式如下是可以運作的

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GridViewDataBid_AspNet._Default" %>


  
code behind
protected void Page_Load(object sender, EventArgs e)
    {
      string[] ary = { "A", "B", "C" };
      GridView1.DataSource = ary;
      GridView1.DataBind();
    }

執行結果如下圖
image
寫起來實在容易。而在 Windows Form這麼做的話,得到的結果是一片空白

private void Form1_Load(object sender, EventArgs e)
    {
      string[] ary = { "A", "B", "C" };
      dataGridView1.DataSource = from s in ary
                                  select new
                                  {
                                    Name = s
                                  };
    }
記得在Form 上的 DataGridView ,要新增一個 Name 的 column

這一段不成功的原因是,DataGridView.DataSource 必須是 IList 介面,包括一維陣列。 IListSource 介面,例如 DataTable 和 DataSet 類別。 IBindingList 介面,例如 BindingList 類別。 IBindingListView 介面,例如 BindingSource 類別。 ( see here )

上一段的程式,只會造成 IEnumable<T>。因此,GridView.DataSource 可以吃,而DataGridView.DataSource 不行。 改一下程式,就可以看到結果了
private void Form1_Load(object sender, EventArgs e)
    {
      string[] ary = { "A", "B", "C" };
      dataGridView1.DataSource = (from s in ary
                                  select new
                                  {
                                    Name = s
                                  }).ToList();
    }
code sample download

2008年8月6日 星期三

DateTime.Parse("中華民國97年2月29日")?

同事問到,如何將 "中華民國97年2月29日" 的字串轉成 DateTime, 與將 DateTime 輸出成 "中華民國97年2月29日"

沒遇過這個問題。

打開 MSDN, 找到了 TaiwanCalendar

開始寫程式囉

      DateTime dt = new DateTime(2008, 2, 29);
      TaiwanCalendar c = new TaiwanCalendar();
      CultureInfo ci = new CultureInfo("zh-TW", true);
      ci.DateTimeFormat.Calendar = c;
      Thread.CurrentThread.CurrentCulture = ci;
      Console.WriteLine(dt.ToLongDateString());

      DateTime dt2;

      dt2 = DateTime.Parse("97-02-29", ci);
      Console.WriteLine(dt2.ToLongDateString());

      dt2 = DateTime.Parse("97/02/29", ci);
      Console.WriteLine(dt2.ToLongDateString());

      dt2 = DateTime.Parse("97-2-29", ci);
      Console.WriteLine(dt2.ToLongDateString());

      dt2 = DateTime.ParseExact("97|02|29", "yy|MM|dd", ci);
      Console.WriteLine(dt2.ToLongDateString());

      dt2 = DateTime.ParseExact("中華民國97年2月29日", "中華民國yy年M月dd日", ci);
      Console.WriteLine(dt2.ToLongDateString());

      dt2 = DateTime.ParseExact("中華民國97年2月29日", "中華民國yy年M月dd日", ci);
      Console.WriteLine(dt2.ToLongDateString());

      dt2 = DateTime.Parse("97/02/29 下午 3:46:01");
      Console.WriteLine(dt2.ToString());

輸出的結果如下
97年2月29日
97年2月29日
97年2月29日
97年2月29日
97年2月29日
97年2月29日

sample code download here

Oracle 學習(1)-- Create User

目前需要用到 Oracle。不過,之前使用 Oracle 已經是十年前的事了(Oracle 7)。 現在的變化應該很大了。 將Study 的過程記錄下來,應該對之後有幫助。
--Create User
set timing off;

spool log\createMyDbReader.log;

create user MyDbReader identified by MyPassword
default tablespace users
temporary tablespace temp
quota unlimited on users
quota unlimited on INDX
quota unlimited on objects
quota unlimited on temp
;
grant create session to MyDbReader;
grant unlimited tablespace to MyDbReader;
grant query rewrite to MyDbReader;

spool off;
exit;

--使用 MyDbReader 登入後更改 password 為 MyNewPassword
connect MyDbReader/MyPassword@MyServer ;

alter user MyDbReader identified by MyNewPassword

--刪除使用者
drop user MyDbReader;

2008年8月4日 星期一

AJAX 之 PageMethod

之前使用 Asp.Net 時,一直使用 UpdatePanel。這個實在是好用。
但是,我卻誤解了,誤以為使用 Ajax 一定會降低頻寬。

我寫了一個範例 , 一個使用傳統的 UpdatePanel,一個使用 PageMethod。
可以使用 fiddler 之類的工具,查到ajax 所使用的 request 及 response 內容。

大小差別如附圖。

image

使用 UpatePanel 的版本,Request (244 bytes)及 Response(648 bytes) 的內容竟然包山包海,根本無法將傳輸的資料量降低。
image
竟然還有 __VIEWSTATE!? 

原來,asp.net ajax team 當初設計 UpdatePanel 的目的,在於簡化開發的過程。因此對於傳回的 request 內容 ,幾乎等同於未 ajax 的版本。相同地, Response 也是幾乎等同於未 ajax 的版本。只不過不必自己塞到不同的 html control 內了。

 

相反地,使用 PageMethod 是一個相當經清的方法。

  1. 將 ScriptManager 的 EnablePageMethods 屬性設寫 true
  2. 在 code behind 程式加上這一段
        [WebMethod]
        [ScriptMethod]
        public static string GetCurrentTime()
        {
          return DateTime.Now.ToString();
        }
  3. 最後,要寫 javascript,讓 button click 時呼叫

function Button2_onclick() {
  PageMethods.GetCurrentTime(ShowTime);
}

function ShowTime(value)
{
  $get("Label2").innerHTML = value;
}
這樣的好處是,傳輸的資料可直接控制。Requet 0 bytes,Response 27 bytes。
Response 的內容為 {"d":"8/4/2008 3:20:09 PM"}。夠精簡吧。 不過這樣一來,資料的內容要塞到 html control 的功夫可不小啊。範例中的simple case,簡直不可能發生。
想想當要顯示一個客戶資料到一個 DetailView 要花多少的javascript程式碼啊!!!

Share with Facebook