前言
以前在微軟的平台,架構一個網站,需要傳統的數據庫處理代碼,業務邏輯層代碼,前端的頁面處理,還有交互程序處理這幾部分的緊密結合,可以說解耦比較困難。網站開發的難度高,更新成本的難度也就高了。就我經驗來說,一個簡單的網站必須是一個可擴展,易跨平台數據復用,易維護的架構。我在這裡拋磚引玉的說說我使用的架構:數據庫 +REST Server+WEB(MVC?) 在下面的文字我盡量少做細節描述,把我目前的做法和大家分享一下就是了。
下載范例
概要
在MS平台上的,數據庫是MS SQL2008 .NET3.5+VS2008,首先建立數據模型,然後生成DataContext(數據庫處理層),然後使用WCF生成REST風格的Web Service,然後再在網站使用Web Service做頁面的處理,對應的網站動態數據交互,以後可以考慮使用MSMQ做消息,然後異步的關心Web Service的Cache等,這是後話,以後有機會再和大家交流。
一:數據庫的操作
前我經常用工廠模式去做,後來發現在大中網站基本用不了那麼復雜的邏輯,因為數據庫的架構基本上是萬古不變的,所以我直接使用C#3.5的Dlinq ,在效率,維護成本上都要高出c#2.0的傳統做法的實現。
OK,用VS2008 創建一個項目 DbDomain,然後新建一個Linq To Sql類,然後在服務器資源管理器鏈接數據庫,找到表,拖過來。就OK了。具體的代碼在附件有。數據庫的結構是:
如上,是兩張簡單的表,會員表和文章表。
直接修改數據庫後,然後再如上步驟即可,對應的*DataContext文件都基本上是固定的格式,有興趣的自己去深入研究。
二:生成RSET 風格的Web Service
為什麼需要Web Service,主要是考慮復用,緩存,數據之間的EVENT通知,還有調試維護等,至於為什麼要生成REST風格的,不明白的請自覺GG之,當然,不是每個方法的實現都用REST風格的,對於安全級別比較高的,我還是會使用傳統的生成的wsdl web service去安排設計。這裡這些暫時不會考慮。
新建一個wcf 應用程序WcfService,創建一個wcf服務Member.svc,范例中只實現了對會員的簡單查詢和錄入:先看看IMember的實現:
namespace WcfService
{
// 注意: 如果更改此處的接口名稱 "IMember",也必須更新 Web.config 中對 "IMember" 的引用。
[ServiceContract]
public interface IMember
{
[OperationContract]
[WebGet(UriTemplate = "User/{id}", ResponseFormat = WebMessageFormat.Json)]
User GetUser(string id);
[OperationContract]
[WebInvoke(UriTemplate = "User/{name}/{password}", ResponseFormat = WebMessageFormat.Xml,Method = "POST")]
int AddUser(string name,string password);
}
}
注意第一行標注[ServiceContract]這是一個可轉換的Service,3.5大部分是這種模式,接下來是[OperationContract]操作方法,相當於asmx的類似於webmethod的這種標注,然後[WebGet(UriTemplate = "User/{id}", ResponseFormat = WebMessageFormat.Json)]這就是表示訪問路徑與相應的格式。我們期望在應用程序訪問http://localhost/member.svc/User/1,能相應Json格式的User數據。這裡的User我並沒有數據的Member,因為敏感數據控制,緩存等考慮,中間做了一層,專用跨平台交互:
[DataContract]
public class User
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name{ get; set; }
}
在dlinq查詢是非常的方便的,例如看看具體的實現:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Member : IMember
{
public User GetUser(string id)
{
DbDomain.TestDbHandlerDataContext dc=new DbDomain.TestDbHandlerDataContext();
return (from x in dc.Member where x.Id.ToString().Equals(id) select new User { Id = x.Id, Name = x.Name }).FirstOrDefault();
}
public int AddUser(string name, string password)
{
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(password)) return -1;
DbDomain.TestDbHandlerDataContext dc = new DbDomain.TestDbHandlerDataContext();
DbDomain.Member clsMember = new DbDomain.Member();
clsMember.Name = name;
clsMember.Password = password;
dc.Member.InsertOnSubmit(clsMember);
dc.SubmitChanges();
return clsMember.Id;
}
}
注意第一句話 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]標注,是指明在IIS裡訪問該service。這裡我沒有做cache等,是直接操作數據庫的,dlinq操作數據之前,都會建立一個 DbDomain.TestDbHandlerDataContext dc = new DbDomain.TestDbHandlerDataContext();查詢類。查詢和更新都需要,語法也是很規范的linq,完全不會出現native sql或者dataset這些東西,全部是模型對象的處理,話外DataContext注意每次使用new的,不要使用static的。
注意,如果要讓你的svc是REST風格的,除了上面的UriTemplate以外,還要修改svc的標注,加上這句:
Factory="System.ServiceModel.Activation.WebServiceHostFactory"
修改web.Config,注意<system.serviceModel>節點上加這句:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
在
<behaviors>
<endpointBehaviors>
<behavior name="RestMemberServiceBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
注意加紅變粗的地方。差不多就注意這幾個地方,具體看我范例的配置吧。
然後再http://localhost:3274/Member.svc/User/1 這樣的去訪問,就會返回json格式的數據:
添加數據庫的方法就是用POST的方式:
var usern = client.UploadString("http://localhost:3274/Member.svc/User/admin/admin", "POST",String.Empty);