顯示具有 程式 標籤的文章。 顯示所有文章
顯示具有 程式 標籤的文章。 顯示所有文章

2014年7月28日 星期一

在 Log4Net 增加 Guid 欄位的紀錄

Log4Net 是一套專業的 Logger, 之前比較常處理的是記錄一般資料型態的紀錄,如 String, Datetime等資料。這篇將針對如何處理 Guid (在 SQL Server 為 uniqueidentifier 的資料型態)來做討論.

開發環境 VS 2012, Log4Net 透過 Nuget 安裝的 2.0.3 版本, 資料庫是 SQL Server 2008 R2

在 Web.Confg 中 ADoNetAppender 的設定, 其中 ORG_ID 在 DB 中是 uniqueidentifier

 <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
      <connectionString value="data source=localhost;initial catalog=LOCAL_DB;integrated security=false;persist security info=True;User ID=user;Password=password"/>
      <commandText value="INSERT INTO SYS_EVENT_LOG ([DATE],[THREAD],[LEVEL],[LOGGER], [LINE], [MESSAGE],[EXCEPTION], [USER_NAME], [CREATE_USER], [IP], [MACHINE_NAME], [ACCESS_MODE], [ORG_ID]) VALUES (@log_date, @thread, @log_level, @logger, @line, @message, @exception, @user_name, @create_user, @ip, @machine_name, @access_mode, @org)"/>
      <bufferSize value="1"/>
      <parameter>
        <parameterName value="@log_date"/>
        <dbType value="DateTime"/>
        <layout type="log4net.Layout.RawTimeStampLayout"/>
      </parameter>
      <parameter>
        <parameterName value="@thread"/>
        <dbType value="String"/>
        <size value="255"/>
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%thread"/>
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@log_level"/>
        <dbType value="String"/>
        <size value="50"/>
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%level"/>
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@logger"/>
        <dbType value="String"/>
        <size value="255"/>
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%logger"/>
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@line"/>
        <dbType value="String"/>
        <size value="10"/>
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%line"/>
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@message"/>
        <dbType value="String"/>
        <size value="4000"/>
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%message"/>
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@exception"/>
        <dbType value="String"/>
        <size value="2000"/>
        <layout type="log4net.Layout.ExceptionLayout"/>
      </parameter>
      <parameter>
        <parameterName value="@user_name"/>
        <dbType value="String"/>
        <size value="50"/>
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%property{user_name}"/>
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@create_user"/>
        <dbType value="String"/>
        <size value="50"/>
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%property{create_user}"/>
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@ip"/>
        <dbType value="String"/>
        <size value="30"/>
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%property{ip}"/>
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@machine_name"/>
        <dbType value="String"/>
        <size value="100"/>
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%property{machine_name}"/>
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@access_mode"/>
        <dbType value="String"/>
        <size value="1"/>
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%property{access_mode}"/>
        </layout>
      </parameter>

      <parameter>
        <parameterName value="@org" />
        <dbType value="Guid" />
        <layout type="log4net.Layout.RawPropertyLayout">
          <conversionPattern value="%property{org}" />
          <key value="org" />
        </layout>
      </parameter>
    </appender>
  </log4net>



在 C# 
            User.BU = Guid.NewID(); // get a new GUID

            log4net.GlobalContext.Properties["ip"] = user.LoginIP;
            log4net.GlobalContext.Properties["machine_name"] = user.LoginIP;
            log4net.GlobalContext.Properties["access_mode"] = "W";
            log4net.GlobalContext.Properties["create_user"] = user.UserAccount;
            log4net.GlobalContext.Properties["user_name"] = user.UserName;

            log4net.GlobalContext.Properties["org"] = user.BU;           

2011年1月13日 星期四

The S.O.L.I.D. Design Principles

The S.O.L.I.D. design principles are a collection of best practices for object-oriented design. All
of the Gang of Four design patterns adhere to these principles in one form or another. The term
S.O.L.I.D. comes from the initial letter of each of the five principles that were collected in the book
Agile Principles, Patterns, and Practices in C# by Robert C. Martin, or Uncle Bob to his friends.
The following sections look at each one in turn.
Single Responsibility Principle (SR P)
The principle of SRP is closely aligned with SoC. It states that every object should only have one
reason to change and a single focus of responsibility. By adhering to this principle, you avoid the
problem of monolithic class design that is the software equivalent of a Swiss army knife. By having
concise objects, you again increase the readability and maintenance of a system.
Open-Closed Principle (OCP)
The OCP states that classes should be open for extension and closed for modification, in that you
should be able to add new features and extend a class without changing its internal behavior. The
principle strives to avoid breaking the existing class and other classes that depend on it, which
would create a ripple effect of bugs and errors throughout your application.
Liskov Substitution Principle (LS P)
The LSP dictates that you should be able to use any derived class in place of a parent class and have it
behave in the same manner without modification. This principle is in line with OCP in that it ensures
that a derived class does not affect the behavior of a parent class, or, put another way, derived classes
must be substitutable for their base classes.
Interface Segregation Principle (IS P)
The ISP is all about splitting the methods of a contract into groups of responsibility and assigning
interfaces to these groups to prevent a client from needing to implement one large interface and a
host of methods that they do not use. The purpose behind this is so that classes wanting to use the
same interfaces only need to implement a specific set of methods as opposed to a monolithic interface
of methods.
Dependency Inversion Principle (DIP)
The DIP is all about isolating your classes from concrete implementations and having them depend on
abstract classes or interfaces. It promotes the mantra of coding to an interface rather than an implementation,
which increases flexibility within a system by ensuring you are not tightly coupled to one
implementation.

2010年11月6日 星期六

Stop ImageButton Postback

JS 中配上這個"終結令"

function foo(event)
{
   // 第一行就堵起來
   if (window.event)
       window.event.returnValue = false;   // IE, Chrome
   else
       event.preventDefault();   // FF
   ...
 
}

在 aps.net

<asp:ImageButton runat="server" id="image" OnClientClick="foo(event)">
包准 Button, ImageButton 不會往後端送 Postback
煞車煞的住!

2010年8月17日 星期二

.NET 的四捨五入處理

這篇寫的真好

Round 真的是四捨五入嗎

在 .NET 中四捨五入最好採用
Math.Round(number, 0, MidpointRounding.AwayFromZero);
否則 Math.Round(???.5) 出現的結果一定會讓您吃驚

2010年6月8日 星期二

半型轉全型

若需要半形轉全型,只要呼叫以下的功能就可以完成. 簡單吧!


private string ToWideStr(String value)
{
// 1028 - TAIWAN
return Microsoft.VisualBasic.Strings.StrConv(value, Microsoft.VisualBasic.VbStrConv.Wide, 1028);
}

// 轉簡體字也很好用!
Microsoft.VisualBasic.Strings.StrConv("中文測試", Microsoft.VisualBasic.VbStrConv.SimplifiedChinese, 2052)

2010年3月26日 星期五

AppendDataBoundItems

AppendDataBoundItems 屬性可讓您在資料繫結發生前,將項目加入至 ListControl 物件。在資料繫結後,項目集合中會包含來自資料來源的項目,以及先前所加入的項目。
例如資料源有男與女
但是也要保留一個空白
可利用 AppendDataBoundItems  = "True"

2009年12月11日 星期五

DotNetZip

DotNetZip 可以快速的開發 ZIP
還可以正確處理中文檔名 (之前有問題)

參考範例:

using (ZipFile zip = new ZipFile(System.Text.Encoding.Default))
{
// add this map file into the "images" directory in the zip archive
zip.AddFile("c:\\images\\personal\\7440-N49th.png", "images");
// add the report into a different directory in the archive
zip.AddFile("c:\\Reports\\2008-Regional-Sales-Report.pdf", "files");
zip.AddFile("ReadMe.txt");
zip.Save("MyZipFile.zip");
}

還是免費的 Yeah!

ps. System.Text.Encoding.Default 是用來處理中文, 否則中文檔名將會變成 ?????

2009年12月6日 星期日

程式圖庫

在 Visual Studio 2008 的安裝目錄下
...\Program Files\Microsoft Visual Studio9.0\Common7\VS2008ImageLibrary\
目錄下可以找到一個壓縮檔 VS2008ImageLibrary.zip
這個壓縮檔案中有需多開發應用程式需要用的圖庫
還包含動畫ㄡ..

2009年11月29日 星期日

關閉 RadWindow 所開啟的視窗

呼叫一個 RadWindow 並讓這個 Window ShowModal
是件容易的事

但是要讓這個 Window 關閉回到呼叫他的視窗該如何做
找了一下範例
發現 Telerik 線上文件也有人再問這個問題

function GetRadWindow()
{
var oWindow = null;
if (window.radWindow)
oWindow = window.RadWindow; //Will work in Moz in all cases, including clasic dialog
else if (window.frameElement.radWindow)
oWindow = window.frameElement.radWindow;//IE (and Moz as well)
return oWindow;
}

// 按下關閉或是離開的按鍵
function Button2_onclick() {
GetRadWindow().Close();
}

2009年11月28日 星期六

.NET Excel

Excel 在 Server 端讀取或是產生
已經變成在商業應用程式中常見的需求

之前利用 VSTO 或是利用 Automation 的方式操作
會遇到幾個瓶頸
1. 慢 (1 sec vs. 40 sec)
2. 應用程式記憶體沒有正常的釋放掉
3. 安全考量 (前兩個問題就很頭痛了,這點也就不需要錦上添花了)

微軟還大書特書的一篇告知開發者不建議 Automation 的方式在伺服器端操作
但是微軟也沒有提出這個問題有何好的解決方法

最近發現 3rd party
有幾個好工具
2. NPOI

Aspose 的 Solution 比較廣泛,除了 Excel, Word, Powerpoint 等Office 文件都可以支援, 當然也不便宜, 使用前請考慮專案預算及 License 策略

NPOI 目前是Free, 但只有 Excel
Java fans 應該不陌生
因為NPOI 就是 .NET POI 啦

2009年11月24日 星期二

一月初到十月底的查詢

這個題目似乎很簡單

假設資料庫中有個表格如下
CREATE TABLE TX (DT DATETIME, EVENT VARCHAR(100))

一般都會以下的查詢

SELECT EVENT FROM TX WHERE DT BETWEEN '2009/1/1' AND '2009/10/31'

但陷阱會出現在 '2009/10/31' 這邊
因為 '2009/10/31' 是代表 '2009/10/31 00:00:00'

下面這筆資料就不會被擷取到
INSERT INTO TX VALUES('2009/10/31 10:10:10', 'SOMETHING WRONG')

所以敘述應改改為

SELECT EVENT FROM TX WHERE DT >= '2009/1/1' AND DT < '2009/11/1'
或是
SELECT EVENT FROM TX WHERE CONVERT(VARCHAR(8), DT, 112)
BETWEEN '20090101' AND '20091031'

會比較好

在 Oracle 也是一樣
SELECT EVENT FROM TX WHERE DT > to_date('2009/1/1', 'YYYY/MM/DD') and DT < to_date('2009/11/1', 'YYYY/MM/DD');

Trunc

Oracle

select trunc(1.3)from dual

SQL Server

select cast(1.3 as int)

結果相同.

2009年11月23日 星期一

資料庫日期函數

整理一下資料庫的日期函數
SQL Server:

有時需要日期 YYYY/MM/DD (字串格式)
SELECT CONVERT(VARCHAR(10),GETDATE(),111)
有時需要日期 YYYY/MM/DD (日期格式)
SELECT CAST (CONVERT(VARCHAR(10),GETDATE(),111) as datetime)

Oracle

有時需要日期 YYYY/MM/DD (字串格式)
SELECT TO_CHAR(SYSDATE, 'YYYY/MM/DD') FROM DUAL
有時需要日期 YYYY/MM/DD (日期格式)
SELECT TRUNC(SYSDATE) FROM DUAL

好像 Oracle 的比較直覺

至於時間部分
SQL Server
SELECT CONVERT(VARCHAR(8),GETDATE(),108)
SELECT TO_CHAR(SYSDATE,'hh24:mi:ss') from dual
好像 Oracle 也比較直覺

2009年11月21日 星期六

RadGrid 擴充欄位處理

一個簡單的範例
要從下面的 SQL 取出資料

select name "姓名", grade "年級", id 學號 from student

想要產生以下的結果

學號 姓名/ 年級
A0001 Philip
3
A0002 Jersey
3


在 RadGrid 要如何實作?

1. 在 RadGrid 中利用 Property Editor 加入一個 Column (Bound Column) 並定義為 Template Column
可利用 Convert this column into Template Column
PS. 不要忘了原先的姓名與年紀兩個欄位,不過要把他們 Visible 變成 False

<telerik:GridTemplateColumn UniqueName="column"  HeaderText="姓名/ 年級">
            <EditItemTemplate>
                <asp:TextBox runat="server"></asp:TextBox>
            </EditItemTemplate>
            <ItemTemplate>
                <asp:Label runat="server" ID="DATA"></asp:Label>
            </ItemTemplate>
        </telerik:GridTemplateColumn>

在 .aspx 中會產生對應的一個 ItemTemplate, Telerik 會先放好一個陽春的 asp:Label 在那邊
記得將個 ID 補齊, 以便後面的程式在 Data Bind 時把資料寫進去

2. 補上 RadGrid.DataItemBound 的事件
3. 當 DataItemBound 被 Trigger 時執行以下的 Code

 protected void Mytable_ItemDataBound(object sender, GridItemEventArgs e)
    {
        // 確定是否是該對應的 SourceId, 其實也可以不用一定要判斷,有時 DataSourceID 可能不會用到
        if (e.Item is GridDataItem && e.Item.OwnerTableView.DataSourceID == "SqlDataSource1")
        {
            Label lbl = e.Item.FindControl("DATA") as Label;
            lbl.Text = (e.Item as GridDataItem)["姓名"].Text" + "<br>" + (e.Item as GridDataItem)["年級"].Text";           
        }
    }


2009年11月19日 星期四

Web.Config 的抓取 ConnectionString

利用 C# 抓取 Web.Config 中的 ConnectionString


String ConnectionStr =
ConfigurationManager.ConnectionStrings["您的設定"].ConnectionString;

2009年10月25日 星期日

使用中的 SQL Server 版本不支援資料型別 'date'

使用中的 SQL Server 版本不支援資料型別 'date'

這個 .NET 問題困擾了我一下
發現 2008/ 2005 Visual Studio 的 DataSource 會將資料庫中的日期型態轉為 date

在 update 或是 insert parameter 中
將 DBType="date" 改成 DBtype="datetime"

只要轉成 DataTime 就可以繞過這個問題

2009年10月20日 星期二

GAC 在哪裡

GAC (Global Assembly Cached)
最近使用 Telerik 的元件,三不五時就報錯
後來發現原來是 Visual Studio 的問題
文件上說將兩個 dll 丟到 GAC
查了一下 GAC 原來在 %windir%\assembly\ 中

使用 .net 提供的 gacutil .exe
不會用?
試試看 gacutil /?


2009年9月3日 星期四

SQL SERVER 2000 的連線問題

最近在維護系統時
發現 Weblogic 連 SQL Server 2000 會出現
連線被拒絕
發現我安裝的 SQL Server 2000 為 DEV 版
因此連 telnet localhost 1433 都會被拒絕

錯誤訊息:

Error establishing socket, connection refused...


若是 SQL Server 2000 ENT 版就可以正常連線

於是利用 Google 找了一下答案
最快的方式就是
安裝 SQL Server SP4 (這個版本有 MSDE/ AS (analytical server) SERVER)

裝完後
就可以正常連線,不再被拒絕連線了 :)

2009年8月31日 星期一

DJ Java Decompiler 中文

DJ Java Decompiler 是個我多年開發 Java 的必備工具
以前對他最大的詬病有兩點
一個是 Color Syntax 對位對的不準,總是會偏兩個字元
另外一點是中文不支援,都是 Unicode 顯示 (\uXXXX)
最近更新 3.11 版本後
發現 Color Syntax 對位已經正確了
至於中文問題也解決了
只要在選單 Settings -> Decompiler Setting 中將
Conver Unicode strings into ANSI strings 選項勾選起來
中文就可以正常的顯示了

好用,推薦給大家!

2009年7月6日 星期一

Android 陣營

garmin-asus:請點我
Acer:請點我
HTC:G1、Magic、Hero等(請點我)
Motorola:請點我
Samsung:i7500(請點我)
Sony Ericsson:請點我