2013年6月25日 星期二

由C#後端讀取CSS檔

--Master page--
<link id="StyleLink" runat="server" rel="stylesheet" type="text/css" />

 

--Masterpage codebehind file--
StyleLink.Attributes.Add("href", ResolveUrl("~/css/main.css"));

2013年5月21日 星期二

淺談多層式架構 (Multi Tiers)

轉貼: http://www.dotblogs.com.tw/topcat/archive/2009/09/11/10577.aspx

從需求談起

我們舉個小例子來理解一般的方式與多層的方式有何不同
假設:我需要顯示最近三個月內,所有營業員的銷售金額成績排名

一般的做法:

在一個畫面中,拉個GridView,一個SqlDataSouce,把需求的語法設定好在SqlDataSouce之後,接著顯示出來就可以了。
這樣的做法,從【資料的展現】【商業邏輯的條件設定】【資料庫的存取】都在一個畫面中處理完畢。
T01
這樣的做法,可以說把所有的東西通通寫在畫面的程式裡面。但是如果哪天想到,我的介面想改成Windows Form、WPF'、SilverLight、PDA去呈現,那麼我們一且都必須重新寫過

分層做法:

如果我們把介面抽離出來,例如使用元件負責處理【商業邏輯條件設定】與【資料的存取】,那麼就會變成如下
T02

此時介面的部分只是負責畫面的呈現,他的資料來源是從中間的元件而來,這樣未來如果想改介面為其他的方式(Windows Form、WPF'、SilverLight、PDA),那麼中間的部分就可不必重寫,只需把介面重寫後再與元件結合
T03


進一步的切分(商業邏輯層、資料存取層)

假設本來的系統,資料的架構比較小、量也不大,因此開發初期使用Access作為資料庫,而當架構變大了,資料變多了,想要用MS SQL Server來處理資料,那麼我們可以很慶幸的,介面層的部分可以不用更動。但是中間層可能有很多的語法、很多的資料存取有所不同了,因此將需要大幅的改寫中間層的程式。但是如果,我們將【商業邏輯條件】與【資料存取動作】在切分開來,那麼中間層的邏輯條件判斷將不須變更,只需將資料存取的部分做改寫。這樣的架構將變成如下。這樣的架構下,未來資料庫就可以變更而不動到商業邏輯層,只需改寫資料存取層。
T04
因此在多層架構中,就會區分為【介面層】、【商業邏輯層】、【資料存取層】這三層,一般成之為【三層架構(3 Tier)】。那又何來的多層呢??在較為大型的系統中,可能區分為各個不同的部分(例如:製造、管理、庫存、銷售、物流、服務維修、…)等。因此中間層可能依照各個不同的屬性,各自獨立在不同的程式中,我們把每個部分設定為一個層的話,這些層式對等的,但是有些時候又需要互相協調合作,此時就可能出現多層的架構,例如:銷售時,須檢查庫存,維護庫存,接著要產生物流的送貨如下圖,因此區分出來的商業邏輯層,不只可以獨立的運作,也可以與其他的商業邏輯層協同運作,形成多層架構。
T05


實踐多層架構的幾個方式

虛擬分層與實體分層

虛擬分層:

所謂的虛擬分層,是指【介面層】、【商業邏輯層】、【資料存取層】在相同的主機上運作,是邏輯上的分層。
T06
由於都在相同的主機上運作,所以架構上單純許多,可以透過類別(Class)來撰寫【商業邏輯層】與【資料存取層】

實體分層:

而實體的分層,就可能這三層分別在不同的主機上,甚至商業邏輯層可能有多部的主機,分別處理各自的商業邏輯(例如:製造、管理、庫存、銷售、物流、服務維修、…都有各自的主機)
T07
在如何實踐上,實體分層就複雜多了,由於主機不同,彼此又要協調合作,變成要處理【分散式交易】。目前小喵所知,可以透過【COM+】、【WCF】來實現這的架構

分層架構需注意【交易(Transaction)的完整性】

通常系統在未分層之時,在處理資料維護的時候,因為維護的程式與語法通通寫在一起,所以要處理交易(Transaction),並不困難,在ADO.NET中,甚至在stored procedure處理即可。但是分層後,很容易就忽略了這個部分,造成資料維護一半發生問題後,沒有辦法全部Rollback,造成資料的異常。

虛擬分層的交易:

由於系統運作在同一主機中,沒有分散交易的問題。因此可以透過TransactionScope(請參考小喵這篇【確保交易的新利器(TransactionScope)初體驗-Part 1(注意Scope.Complete的位置)】)來輕鬆解決這個問題。

實體分層的交易:

小喵剛提到,實體分層可以透過【COM+】與【WCF】來實現這個架構。但是或許有些人會問:WebService不是也支援Transaction,那使用【WebService】是不是也可以呢?經過小喵測試結果(Web Service呼叫Web Service使用Transaction確保交易完整性測試報告),WebService呼叫WebService的時候,無法將兩個WebService包成一個完整的交易(Transaction),因此單純的使用WebService是不行的。

總結

多層系統架構,可以讓我們的系統變得更有彈性,讓介面與資料庫可以更靈活的抽換。而且開發過程中,由於切分了不同的層。也可以讓不同的人負責不同的層級,多人一起協同開發。有些然專門處理畫面設計,有些人負責寫商業邏輯,有些人負責資料存取。而商業層級,也可以由負責不同系統的人,開發他自己的部分,讓彼此專注於自己的Domain KnowHow開發商業邏輯元件,之後再結合運作。對於開發大型的系統,建議最好能夠用多層的架構來開發。

2013年5月20日 星期一

專案檔設計、CodeFile、CodeBehide

新網站 >> CodeFile
新專案 >> Web應用程式 >> CodeBehind , 產生xxx.Deigner.cs

空白Solution可裝 新增網站 或是 新增專案

2013年5月14日 星期二

避免從Oracle DB要 Big5 資料時 亂碼

<add name="SICSOLEConnStr" connectionString="Provider=MSDAORA;User ID=user;password=pwd;Data Source=PROD;Persist Security Info=False" providerName="System.Data.OleDb"></add>


OleDbParameter 類別

http://msdn.microsoft.com/zh-tw/library/system.data.oledb.oledbparameter(v=vs.80).aspx

2013年4月26日 星期五

無法顯示 IIS 管理員使用者

在伺服器管理員中檢查一下IIS角色有沒有安裝IIS的管理工具中的『管理服務』,沒有的話把它安裝起來,安裝完成後開啟IIS管理工具可在IIS伺服器層級或網站層級中的功能檢視的管理區塊中看到『管理』,在管理區塊裡有IIS管理員使用者及IIS管理員權限,我猜這應該是你想要的功能吧,你可以試試看。

2013年4月24日 星期三

AjaxControlToolkit中CalendarExtender 樣式修改、重置、清除



The Official Microsoft ASP.NET Site上有一个很强大的控件AJAX Control Toolkit,其功能非常完整,几乎涵盖了表现层方面各种应用,使用也很方便,有中文详细支持,能给程序员很大帮助。


我现在使用的其中一款控件叫做CalendarExtender,其实是一个DatePicker(日期选择器),这个控件可以直接在Input控件上添加「扩展程序」,就完成了所有工作。
偏移
让我意外的是,这个控件在我的页面上工作时候样式似乎有些不正常。
页面漂移了!我仔细检查了FireBug,发现下面的样式中的padding影响了其td。(页面可不是我设计的“`)
Firebug
如果修改CSS,就带来了大量的页面需要修改class/id,所以我只能修正CalendarExtender。(话说人家jQuery在这儿丝毫不受影响,全部元素都覆盖了样式,AJAX Control Toolkit在样式上还是不如jQuery)
我在CalendarExtender外面包了一层div,再覆盖CalendarExtender的td属性。
Html代码:
<div>
<asp:TextBox ID="TbBirthday" runat="server"></asp:TextBox>
<cc1:CalendarExtender ID="TbBirthday_CldEx" runat="server" Enabled="True" TargetControlID="TbBirthday" FirstDayOfWeek="Monday" Format="yyyy-MM-dd" PopupPosition="BottomRight">
</cc1:CalendarExtender></div>
CSS代码:
/*bugs for CalendarExtends*/
.content .table .calendar td {/*.calender td 前的类是我网页中的上层元素*/
margin: 0px;
padding: 0px;
}
这样一来,就可以解决这个问题了。
修正
最后,附送一个汉化控件的技巧:其实下载后,已经有语言包在下载包里面,之所以没有启用中文,是因为没有打开ScriptManager的全球化控制,把ScriptManager的EnableScriptGlobalization改为true即可。
Asp.NET代码:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnableScriptGlobalization="True">
</asp:ScriptManager>

2013年4月18日 星期四

判別中文字數

private void button1_Click(object sender, EventArgs e)
{
    byte[] byteStr = Encoding.GetEncoding("big5").GetBytes(textBox1.Text); //把string轉為byte
    label1.Text = byteStr.Length.ToString(); //取byte的長度, 中文字就會算2碼了
}

2013年3月7日 星期四

isPostBack

if(!ispostback){
第一次讀取時 才執行
}

已讀過 就不再執行


isPostBack: 是否已經讀取

2013年3月6日 星期三

剔除重複字串


轉:http://www.dotblogs.com.tw/hung-chin/archive/2011/10/04/38717.aspx


剔除重複字串

Regex.Split 方法 請參考MSDN
然後把每一行的字串塞到陣列str裡面去
而陣列有一個Distinct方法,可以剔除重除字串
所以接著只要用foreach 把剩下的值填回去textBox1去就完成了
foreach (string strlist in str.Distinct())
{
    textBox1.Text += strlist + "\r\n";
}

以下為本例完整程式碼

01using System;
02using System.Collections.Generic;
03using System.ComponentModel;
04using System.Data;
05using System.Drawing;
06using System.Linq;
07using System.Text;
08using System.Windows.Forms;
09using System.Text.RegularExpressions;
10namespace ex24
11{
12    public partial class Form1 : Form
13    {
14        public Form1()
15        {
16            InitializeComponent();
17        }
18        private void button1_Click(object sender, EventArgs e)
19        {
20            string[] str = Regex.Split(textBox1.Text, "\r\n");
21            textBox1.Text = "";
22            foreach (string strlist in str.Distinct())
23            {
24                textBox1.Text += strlist + "\r\n";
25            }
26        }
27    }
28}