2010-11-15

[Tips]Javascript-判斷變數,物件是否存在

在JavaScript中判斷變數是否存在

if (typeof(_varName) == 'undefined')

  …the variable is not exist.

在jQuery中判斷下拉選單裡是否有特定value的option存在

if (jQuery("#" + _objId + " option[value='" + _value + "']").length > 0)

2010-10-23

[Tips] Entity Framework and JSON

需求

提供JSON的格式資料,但是不要將所有的entity欄位都輸出.

 

方式

 

輸出所有欄位

   1: using (MyStockEntities entities = new MyStockEntities())
   2: {
   3:     JavaScriptSerializer js = new JavaScriptSerializer();
   4:     return js.Serialize(entities.CodeStocks);
   5: }

 


輸出需要的欄位



   1: using (MyStockEntities entities = new MyStockEntities())
   2: {
   3:     JavaScriptSerializer js = new 
   4:     JavaScriptSerializer();
   5:     var results = from cols in entities.CodeStocks
   6:         select new
   7:         {
   8:             StockId = cols.StockId,
   9:             StockName = cols.StockName,
  10:             StockType = cols.StockType
  11:         };
  12:     return js.Serialize(results);
  13: }

2010-03-23

[code snippet]清除html tag並清除多餘的空白

//清除Html Tag
string stripped = Regex.Replace(content, @"<(.|\n)*?>", string.Empty);

//清除多餘的空白
Regex r = new Regex(@"\s+");
stripped = r.Replace(stripped,@" ");

2008-02-18

玩玩asp.net 2.0的caching系列二 - RemoveOutputCacheItem

在asp時代,要作cache通常是用application來存資料,
要完整一點的.就是自己寫個class來操作application控制要cache的資料.

但是在asp.net,頁面要cache變得簡單許多.
只要一行

<%@ OutputCache Duration="60" VaryByParam="None" %>

就可以了,
但是,現在問題又來了,
客戶希望後台新增完後他要立即可以從前台看到更新的資料.
先前在網路上看到是有說只要頁面有修改outputcache就會被清除.
但是...這是在測試時候的方式,
在production環境的頁面應該是不能讓客戶每次更新完就去動一下頁面.
要解決這問題,
可以使用HttpResponse.RemoveOutputCacheItem
用法如下 :

HttpResponse.RemoveOutputCacheItem("/default.aspx");

假設你的default.aspx有設定了outputcache,那你可以新增一個管理cache的頁面.
在那個頁面上有個按鈕,點下後呼叫上面的程式.
而RemoveOutputCacheItem所帶的參數就是你的頁面的絕對路徑(不能使用"../"這種相對路徑).

測試網址:

OutputCache頁面 : http://vip.blueshop.com.tw/ajun/cachetest.aspx
Cache管理頁面 : http://vip.blueshop.com.tw/ajun/cachemanager.aspx

outputCache頁面在上一篇介紹過了,而管理的頁面中有兩個功能,
remove cache才是這次的測試範例.

只要確定網址正確,按下remove cache後,該頁面的outputcache就會被清除,
再次瀏覽outputcache的頁面後就會是被更新後的資料了.

問題到這大致上已經ok了,
但是...還是有點狀況,
因為後台維護的資料是最新消息,
而除了首頁外,還有其他的頁面也都會顯示最新消息,
所以如果要用RemoveOutputCacheItem一筆一筆清除cache似乎有點麻煩,
所以下一篇將會是說明怎麼處理這樣的問題.
ps.範例中有這個的程式碼,如果等不及想要知道解決方案的話,可以直接看code.

範例下載:
http://ajunlee.googlepages.com/CacheTest.rar

玩玩asp.net 2.0的caching系列一 - OutputCache與Substitution

作網站的首頁的時候,通常為了增加效能,都會作一些cache的動作,
而在asp.net中,要作將網頁作cache很簡單,
如果要cache整個頁面,只要在aspx中加上下面這段

<%@ OutputCache Duration="60" VaryByParam="None" %>

這樣可以讓你的頁面cache 60秒.
如果你的網址如下

ShowCity.aspx?city=101

也就是會因為參數不同而有不同結果,而你也希望能快取這些頁面,
那就將設定改為

<%@ OutputCache Duration="60" VaryByParam="city" %>

如果有多個參數的話,那就以分號(;)區隔就可以了,例如

<%@ OutputCache Duration="60" VaryByParam="city;zipcode" %>

可是現在問題來了.
如果首頁都是公開的資料那也就沒有甚麼問題,
但是現在首頁要放個登入者的名稱,
讓使用者知道自己已經登入,而且知道自己叫甚麼名字.
而整頁作outputcache的話,一連到網頁可能會看到別人的名字...
一開始,是用ajax的方式,在也面呈現以後,
透過javascript去呼叫一隻aspx取得登入資料,然後顯示在某個div裡面.

但後來發現asp.net 2.0中有個Substitution的控制項可以解決這樣的問題,

而Substitution 的用法如下:

aspx

<asp:Substitution ID="Substitution1" runat="server" MethodName="GetDateTime" />

aspx.cs

public static string GetDateTime(HttpContext context)
{
    return "主機時間 : " + DateTime.Now.ToString();
}

範例網址 : http://vip.blueshop.com.tw/ajun/cachetest.aspx

點選上面的範例網址,然後重新整理幾次,
你會發現上面的主機時間60秒才會更新.
但下面的主機時間是每次都會更新.

 

參考網址:
http://dotnetjunkies.com/QuickStartv20/aspnet/doc/ctrlref/standard/substitution.aspx

範例下載:
http://ajunlee.googlepages.com/CacheTest.rar

2008-02-01

取得MS SQL中資料欄位的描述內容

用ado.net的connection.GetSchema取得資料表結構算是蠻方便的.
但差的一點就是取不到欄位的說明.
因為又要開始寫文件了.而之前寫的SchemaGen不能支援MS SQL 2005.
所以現在正在著手寫SchemaGen 2005版.
另外也練習使用所謂的design pattern來進行...
至於用哪個...先試試看再說...

回到主題.
之前其實有寫過相關的主題.
不過當初主要是說明用T-SQL維護欄位的描述.
現在再針對::fn_listextendedproperty加一些說明

如果要針對某個資料表的某個欄位取得
可以使用下面的語法

select value form ::fn_listextendedproperty(NULL, 'user', 'dbo', 'table', N'資料表名稱', 'column', N'欄位名稱')

如果要取得某個資料表中所有欄位說明的話,可以使用

select * form ::fn_listextendedproperty(NULL, 'user', 'dbo', 'table', N'資料表名稱', 'column',NULL)

另外.如果你的資料表也有設定說明的話,
可以使用下面的語法取得資料表的說明

select * form ::fn_listextendedproperty(NULL, 'user', 'dbo', 'table', N'資料表名稱',NULL,NULL)

當然.要取的所有資料表的說明就是用下面這個

select * form ::fn_listextendedproperty(NULL, 'user', 'dbo', 'table',NULL,NULL,NULL)

另外,上面的參數中有使用NULL的,也可以改用default.意義應該是相同的.例如

select * form ::fn_listextendedproperty(default, 'user', 'dbo', 'table',default,default,default)

而修改或是新增欄位或是資料表說明的話,
可以參考上次寫的T-SQL維護欄位的描述,
使用sp_addextendedproperty及sp_updateextendedproperty來處理

 

相關連結 :

fn_listextendedproperty (Transact-SQL)
http://msdn2.microsoft.com/en-us/library/ms179853.aspx

sp_addextendedproperty (Transact-SQL)
http://msdn2.microsoft.com/en-us/library/ms180047.aspx

sp_updateextendedproperty (Transact-SQL)
http://technet.microsoft.com/zh-tw/library/ms186885.aspx

2008-01-26

玩玩.net的ildasm與ilasm

之前有個朋友拿個vb6的程式給我.
說這是他請別人寫的,需要密碼才能開啟使用,
可是他忘了密碼是甚麼,而且沒有原始碼,
希望看看有沒有辦法"找到".

程式的功能是甚麼已經有點不記得了,因為不是重點.
重點是他的密碼並沒有在資料庫中,因為翻遍資料庫(Access)中的資料表沒有找到任何訊息.
所以猜測密碼應該是在包在程式裡了.

所以直接用十六進位編輯器(ultraedit)開啟那個執行檔.
在檔案中看到password的字樣,而就在附近看到了"疑似"密碼的字串.
然後使用那個密碼試著登入.果然真的是密碼...

不知道各位看了上面這個例子會有甚麼想法!!

回到主題.
今天要介紹的是ildasm跟ilasm的功能.
在msdn上的介紹寫著 :

MSIL 反組譯工具是 MSIL 組譯工具 (Ilasm.exe) 的附屬工具。Ildasm.exe 使用包含 Microsoft Intermediate Language (MSIL) 程式碼的可攜式執行檔 (PE),並建立可以做為 Ilasm.exe 的輸入檔的文字檔。

如果你跟我一樣看了還是不懂他是用來做甚麼的話,那就先往下看.
為了測試,我們要先寫個主控台程式(ConsoleApplication).
主要的功能如下:

讓使用者輸入帳號密碼,
然後判斷是否跟我們設定好的字串相同.
如果相同就顯示welcome,
如果不同就顯示Access Deny.

程式碼如下:

using System;

namespace LoginConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            string UserId = "ajun";
            string UserPwd = "password";

            Console.Write("Please enter your id : ");
            string uid = Console.ReadLine();
            Console.Write("Please enter your password : ");
            string pwd = Console.ReadLine();

            if ((uid == UserId) && (UserPwd == pwd))
            {
                Console.WriteLine("Welcome!");
            }
            else
            {
                Console.WriteLine("Access Deny!");
            }
        }
    }
}

寫好後編譯成exe檔.(假設我們編譯完後的執行檔的名稱為 LoginConsole.exe)
然後開啟一個dos視窗.
因為我是用vs.net 2005.
所以要將路徑切換到到
C:\Windows\Microsoft.NET\Framework\v2.0.50727
因為ildasm.exe是放在這個路徑下.
當然.如果你是透過"Visual Studio 2005命令提示字元"啟動命令視窗的話,就不用切換目錄了.

然後執行下列的指令 :

ildasm LoginConsole.exe

這時就會跳出ildasm的視窗如下 :

ildasm001

點開其中的 Main : void(string[])
就可以看到如下反組譯的視窗畫面

ildasm002

而內容如下 :

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // 程式碼大小       104 (0x68)
  .maxstack  2
  .locals init ([0] string UserId,
           [1] string UserPwd,
           [2] string uid,
           [3] string pwd,
           [4] bool CS$4$0000)
  IL_0000:  nop
  IL_0001:  ldstr      "ajun"
  IL_0006:  stloc.0
  IL_0007:  ldstr      "password"
  IL_000c:  stloc.1
  IL_000d:  ldstr      "Please enter your id : "
  IL_0012:  call       void [mscorlib]System.Console::Write(string)
  IL_0017:  nop
  IL_0018:  call       string [mscorlib]System.Console::ReadLine()
  IL_001d:  stloc.2
  IL_001e:  ldstr      "Please enter your password : "
  IL_0023:  call       void [mscorlib]System.Console::Write(string)
  IL_0028:  nop
  IL_0029:  call       string [mscorlib]System.Console::ReadLine()
  IL_002e:  stloc.3
  IL_002f:  ldloc.2
  IL_0030:  ldloc.0
  IL_0031:  call       bool [mscorlib]System.String::op_Equality(string,
                                                                 string)
  IL_0036:  brfalse.s  IL_0044
  IL_0038:  ldloc.1
  IL_0039:  ldloc.3
  IL_003a:  call       bool [mscorlib]System.String::op_Equality(string,
                                                                 string)
  IL_003f:  ldc.i4.0
  IL_0040:  ceq
  IL_0042:  br.s       IL_0045
  IL_0044:  ldc.i4.1
  IL_0045:  stloc.s    CS$4$0000
  IL_0047:  ldloc.s    CS$4$0000
  IL_0049:  brtrue.s   IL_005a
  IL_004b:  nop
  IL_004c:  ldstr      "Welcome!"
  IL_0051:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0056:  nop
  IL_0057:  nop
  IL_0058:  br.s       IL_0067
  IL_005a:  nop
  IL_005b:  ldstr      "Access Deny!"
  IL_0060:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0065:  nop
  IL_0066:  nop
  IL_0067:  ret
} // end of method Program::Main

而從這內容就可以很清楚的看到我們所設定的帳號密碼.
到這.我想大家應該比較清楚ildasm.exe的功能了.

再來在說一下ilasm.exe,
ildasm是用來做反組譯的,
而ilasm就是用來作組譯用的.
至於怎麼用.看一下下面的用法.

現在我們先用ildasm.exe來產生剛剛所寫的程式的PE檔.
語法如下 :

ildasm /source LoginConsole.exe /out:LoginConsoleFake.txt

其中的/source參數是用來"顯示原始程式行做為註解".
然後我們就可以得到下面這個LoginConsoleFake.txt的檔案.

//  Microsoft (R) .NET Framework IL Disassembler.  Version 2.0.50727.42
//  Copyright (c) Microsoft Corporation.  All rights reserved.

// Metadata version: v2.0.50727
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 2:0:0:0
}
.assembly LoginConsole
{
  .custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = ( 01 00 07 31 2E 30 2E 30 2E 30 00 00 )             // ...1.0.0.0..
  .custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( 01 00 24 65 30 31 65 31 37 32 31 2D 37 32 62 63   // ..$e01e1721-72bc
                                                                                                  2D 34 33 61 62 2D 38 65 62 62 2D 34 66 66 38 34   // -43ab-8ebb-4ff84
                                                                                                  31 62 65 34 65 37 36 00 00 )                      // 1be4e76..
  .custom instance void [mscorlib]System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool) = ( 01 00 00 00 00 )
  .custom instance void [mscorlib]System.Reflection.AssemblyTrademarkAttribute::.ctor(string) = ( 01 00 00 00 00 )
  .custom instance void [mscorlib]System.Reflection.AssemblyCopyrightAttribute::.ctor(string) = ( 01 00 13 43 6F 70 79 72 69 67 68 74 20 28 43 29   // ...Copyright (C)
                                                                                                  20 20 32 30 30 38 00 00 )                         //   2008..
  .custom instance void [mscorlib]System.Reflection.AssemblyProductAttribute::.ctor(string) = ( 01 00 0C 4C 6F 67 69 6E 43 6F 6E 73 6F 6C 65 00   // ...LoginConsole.
                                                                                                00 )
  .custom instance void [mscorlib]System.Reflection.AssemblyCompanyAttribute::.ctor(string) = ( 01 00 00 00 00 )
  .custom instance void [mscorlib]System.Reflection.AssemblyConfigurationAttribute::.ctor(string) = ( 01 00 00 00 00 )
  .custom instance void [mscorlib]System.Reflection.AssemblyDescriptionAttribute::.ctor(string) = ( 01 00 00 00 00 )
  .custom instance void [mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) = ( 01 00 0C 4C 6F 67 69 6E 43 6F 6E 73 6F 6C 65 00   // ...LoginConsole.
                                                                                              00 )

  // --- 以下為自動加入的自訂屬性,請勿取消註解 -------
  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 )

  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx
                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.
  .hash algorithm 0x00008004
  .ver 1:0:0:0
}
.module LoginConsole.exe
// MVID: {71069530-5126-4026-B70A-03F69CFFD29A}
.imagebase 0x00400000
.file alignment 0x00001000
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x009C0000

// =============== CLASS MEMBERS DECLARATION ===================

.class private auto ansi beforefieldinit LoginConsole.Program
       extends [mscorlib]System.Object
{
  .method private hidebysig static void  Main(string[] args) cil managed
  {
    .entrypoint
    // 程式碼大小       104 (0x68)
    .maxstack  2
    .locals init ([0] string UserId,
             [1] string UserPwd,
             [2] string uid,
             [3] string pwd,
             [4] bool CS$4$0000)
    .language '{3F5162F8-07C6-11D3-9053-00C04FA302A1}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}'
// Source File 'D:\Project\LoginConsole\LoginConsole\Program.cs'
//000010:         {
    IL_0000:  nop
//000011:             string UserId = "ajun";
    IL_0001:  ldstr      "ajun"
    IL_0006:  stloc.0
//000012:             string UserPwd = "password";
    IL_0007:  ldstr      "password"
    IL_000c:  stloc.1
//000013:
//000014:             Console.Write("Please enter your id : ");
    IL_000d:  ldstr      "Please enter your id : "
    IL_0012:  call       void [mscorlib]System.Console::Write(string)
    IL_0017:  nop
//000015:             string uid = Console.ReadLine();
    IL_0018:  call       string [mscorlib]System.Console::ReadLine()
    IL_001d:  stloc.2
//000016:             Console.Write("Please enter your password : ");
    IL_001e:  ldstr      "Please enter your password : "
    IL_0023:  call       void [mscorlib]System.Console::Write(string)
    IL_0028:  nop
//000017:             string pwd = Console.ReadLine();
    IL_0029:  call       string [mscorlib]System.Console::ReadLine()
    IL_002e:  stloc.3
//000018:
//000019:             if ((uid == UserId) && (UserPwd == pwd))
    IL_002f:  ldloc.2
    IL_0030:  ldloc.0
    IL_0031:  call       bool [mscorlib]System.String::op_Equality(string,
                                                                   string)
    IL_0036:  brfalse.s  IL_0044

    IL_0038:  ldloc.1
    IL_0039:  ldloc.3
    IL_003a:  call       bool [mscorlib]System.String::op_Equality(string,
                                                                   string)
    IL_003f:  ldc.i4.0
    IL_0040:  ceq
    IL_0042:  br.s       IL_0045

    IL_0044:  ldc.i4.1
    IL_0045:  stloc.s    CS$4$0000
    IL_0047:  ldloc.s    CS$4$0000
    IL_0049:  brtrue.s   IL_005a

//000020:             {
    IL_004b:  nop
//000021:                 Console.WriteLine("Welcome!");
    IL_004c:  ldstr      "Welcome!"
    IL_0051:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_0056:  nop
//000022:             }
    IL_0057:  nop
    IL_0058:  br.s       IL_0067

//000023:             else
//000024:             {
    IL_005a:  nop
//000025:                 Console.WriteLine("Access Deny!");
    IL_005b:  ldstr      "Access Deny!"
    IL_0060:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_0065:  nop
//000026:             }
    IL_0066:  nop
//000027:         }
    IL_0067:  ret
  } // end of method Program::Main

  .method public hidebysig specialname rtspecialname
          instance void  .ctor() cil managed
  {
    // 程式碼大小       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method Program::.ctor

} // end of class LoginConsole.Program

// =============================================================

// *********** 反組譯作業完成 ***********************
// 警告: 已建立 Win32 資源檔 LoginConsoleFake.res

再來我們將這個檔案做些小調整.
從檔案中我們可以很容易看出哪個是帳號密碼的設定.
所以我們直接改一下密碼.將他改為1234.

IL_0007:  ldstr      "password"
改為
IL_0007:  ldstr      "1234"

存檔後.在dos的視窗輸入下列指令

ilasm LoginConsoleFake.txt

當執行完成後,它會產生一個LoginConsoleFake.exe的檔案.
這時你就可以執行它.然後輸入新的密碼看看!!

我想這時你應該對於ildasm跟ilasm有初步的認識了...
雖然這並不是一個很正面的例子.
但是,我想應該是可以讓人比較有興趣...

其實,ildasm有更正面的用法,
像是黑暗執行緒寫的這篇,

或是你想要看看對於sqlconnection使用using跟使用close()與Dispose(),
在編譯後所進行的動作有甚麼差異.
也都是可以透過這個工具來進行.

最後,你或許會覺得.net的程式就這麼"透明",這麼不安全嗎??
其實有攻就有防.
下個主題或許可以來說一下.net的"混淆器"(obfuscator).

2007-12-27

mssql只取得時間欄位中的日期資料(Get Date from DateTime)

DateTime的欄位內容為 2007/12/27 18:26:29.597
現在想要只取得2007/12/27而且要保持為日期型態.
也就是要取得2007/12/27 00:00:00的結果
原本是想用format的方式來取得字串結果,然後再轉型態.

不過這樣的語法似乎太長了點.
所以改成下面的方式

select dateadd(dd,0,datediff(dd,0,getdate()))

先使用datediff取得該日期的數值,
再使用dateadd去取得此數值所代表的日期.

雖然使用select cast(getdate() as int)雖然也是可以將日期轉為數值,
但是只要超過12:00就會取得隔天的日期(應該是4捨5入的原因)

select cast('2007/12/27 12:00:00' as datetime)
-- 2007-12-27 12:00:00 000
select cast(cast('2007/12/27 12:00:00' as datetime) as int)
-- 39442
select cast('2007/12/27 11:59:59' as datetime)
-- 2007-12-27 11:59:59
select cast(cast('2007/12/27 12:59:59' as datetime) as int)
-- 39941

所以還是使用datediff的方式來取得日期的數值比較好.

2007-12-26

玩玩紙模型

今天發現幾個不錯的紙模型網站

第一彈 : EX-S 鋼彈
EX-S PaperModel_02
原創者的網誌:http://blog.naver.com/7200ss
不過現在很難找到下載點了.所以要用力google一下

GUNDAM紙模型的下載與作品
如果是鋼彈迷的話可以到這挖寶,不過可能手腳要快點.

Canon的Creative Park
裡面的3D-papercraft有許多紙模型可以下載,
如果有打算做個城鎮的話,可以看一下他的craftown,
沒太多錢可以弄個鐵道模型城鎮的話,可以先玩玩這個.
另外他的buildings看起來也是超優的!
 

YAMAHA的Paper Craft
既然是YAMAHA的網站,
主要的當然就是摩托車的紙模型了!
不過除了摩托車外,還有一些動物及日本風情的紙模型也是不錯的!
另外,還有提供紙模型的教學
http://www.yamaha-motor.co.jp/global/entertainment/papercraft/howto/index.html
影片式的教學讓你一看就懂.
http://www.yamaha-motor.co.jp/global/entertainment/papercraft/howto/0002.html

3D紙模型網
我想只要有在玩紙模型的應該都知道這個網站!!

真的要去買台彩色印表機了...
不然我的機器人都只能是鐵灰色的...

2007-12-13

DateTime Formet 與 CultureInfo

今天收到一個問題,
是要將時間格式顯示為
Thu,13 Dec 2007 08:23:41 +08:00

大致上先想到的是取得格林威治時間
也就是用

DateTime.Now.ToUniversalTime().ToString()

因為台灣的時區是 +8,
所以取得的時間會是台灣時間減8小時.

他這樣的格式會顯示
2007/12/13 上午 08:23:41

然後在ToString()的格式加上"r"
如 :

DateTime.Now.ToUniversalTime().ToString("r");

這樣的結果會顯示
Thu, 13 Dec 2007 08:23:41 GMT

已經有點接近我們要的格式了,
不過還少了+08:00
查了一下,可以在格式中加個zzz來達成
但是zzz跟r似乎是不能一起使用.
所以改成如 :

DateTime.Now.ToUniversalTime().ToString("ddd,d MMM yyyy hh:mm:ss zzz");

這樣的結果變成
星期四,13 十二月 2007 08:23:41 +08:00

因為作業系統的地區與語言選項的設定是預設的中文(台灣)
所以會顯示中文字在時間字串中.
所以要再使用CultureInfo改一下.

System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("en-US");
DateTime.Now.ToUniversalTime().ToString("ddd,d MMM yyyy hh:mm:ss zzz",ci);

這時資料就會是以英文(美國)的格式呈現,如下:
Thu,13 Dec 2007 08:23:41 +08:00

上面這樣大致上就可以得到我們要的結果,
不過,每次顯示都要再丟ci進去.
所以,如果不想每次都丟ci的話,
那就是再加一行code
如下

System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("en-US");
System.Threading.Thread.CurrentThread.CurrentCulture = ci;
DateTime.Now.ToUniversalTime().ToString("ddd,d MMM yyyy hh:mm:ss zzz");

到此.收工.

參考資料 :

Standard DateTime Format Strings
http://msdn2.microsoft.com/en-us/library/az4se3k1(VS.71).aspx

Custom DateTime Format Strings Output Examples
http://msdn2.microsoft.com/en-us/library/hzz3aycd.aspx

CultureInfo 類別
http://msdn2.microsoft.com/zh-tw/library/system.globalization.cultureinfo(VS.80).aspx

2007-11-20

C#中??的用法

改用c# 2.0也一年多了,
最近才發現??的用法.

??這個operator的用法如下

string message = null;
string result = message ?? "message is null";
Console.WriteLine(result); //列印出 message is null

 

string message = "I am not null";
string result = message ?? "message is null";
Console.WriteLine(result); // 列印出 I am not null

另外,在數值方面,

int x = null;

這樣是會產生編譯錯誤(Cannot convert null to 'int' because it is a non-nullable value type).
所以如果你就是要宣告一個int而可以是個null的內容的話,
那就是用

int? x = null;

再搭配??的用法如下

int? x = null;
int y = x ?? -1;
Console.WriteLine(y.ToString()); //列印出 -1

當開發機是Windows on ARM...

 在MacOS上要使用windows去編譯一些程式常常會遇到一些plamform的問題... - cmake build failed 當使用 cmake -S . -B build 要建立 build system files 原本的專案是在x64上, 所以直接執行會直接使用A...