Thứ Năm, 28 tháng 5, 2009

Using LINQ with SharePoint 2007 Objects

 

I’ve waiting for “LINQ to SharePoint” feature from Microsoft a long time. Now, with SharePoint SP2 and VS 2008, We’ll easy to use LINQ feature to query SharePoint data.

Before, I tried to use “LINQ for SharePoint” from CodePlex, but I didn’t happy. I think the support from Microsoft for LINQ to SharePoint is the best.

Thanks for the improvement. I’m waiting for some improve features in next version of SharePoint, maybe SharePoint 2010.

Here are my code using LINQ with SharePoint data

 

   1: SPSite site = new SPSite("http://basquang:8001");
   2: SPWeb web = site.RootWeb;
   3: var listItems = from SPListItem item in web.Lists["Tasks"].Items
   4:                 where DateTime.Parse(item["Due Date"].ToString()) <= DateTime.Today
   5:                 select item;
   6: foreach (var item in listItems)
   7: {
   8:     Console.WriteLine(item.Title);
   9: }

Cascading Drop-Down List trong InfoPath Browser form

Chúng ta biết rằng việc sử lý giao diện theo kiểu master/detail hay cascading là rất hay gặp. Lấy ví dụ cho một cascading phổ biến là Address (địa chỉ). Tôi có 3 drop-down list bao gồm: Tỉnh thành phố (province), quân huyên (district) và phường xã (ward). Khi tôi select tỉnh thành phố, thì drop-down list quận huyện sẽ tự động fill theo tỉnh thành phố đó. Tương tự khi tôi select quận huyện, thì drop-down list phường xã cũng fill theo quận huyện đó.

A21319952F68E79E_311_0[1]

Bài toán này, nếu sử dụng InfoPath không hỗ trợ browser form thì sẽ rất là đơn giản. Chúng tả chỉ cần sử dụng tính năng Filter của InfoPath control là đủ. Tuy nhiên, đối với InfoPath Browser support, các bạn biết rằng không sử được tính năng filter trên, dó đó buộc chúng ta phải can thiệp vào InfoPath Object Model. Trên web cũng có một số bài viết về việc xử lý Cascading Drop-Down List trong InfoPath sử dụng Web Service. Tuy nhiên, điều này hơi bất cấp trong việc deploy webservice và lưu trữ giữ liệu trên SQL để cho Web Service query.

Hôm nay tôi giới thiệu cho các bạn một cách xử lý Cascading  Drop-Down List nhiều cấp cho InfoPath browser form support bằng cách sử dụng InfoPath Object Model và XPath query.

Trước hết chúng ta thiết kế một XML file để lưu trữ dữ liệu cho các drop-down như sau:

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <DiaChi>
   3:   <TinhTP>
   4:     <tenTinhTP>Hanoi</tenTinhTP>
   5:     <QuanHuyen>
   6:       <tenQuanHuyen>Cau Giay</tenQuanHuyen>
   7:       <PhuongXa>
   8:         <tenPhuongXa>Dich Vong</tenPhuongXa>
   9:       </PhuongXa>
  10:       <PhuongXa>
  11:         <tenPhuongXa>Mai Dich</tenPhuongXa>
  12:       </PhuongXa>
  13:     </QuanHuyen>
  14:     <QuanHuyen>
  15:       <tenQuanHuyen>Dong Da</tenQuanHuyen>
  16:       <PhuongXa>
  17:         <tenPhuongXa>Dong Tam</tenPhuongXa>
  18:       </PhuongXa>
  19:     </QuanHuyen>
  20:   </TinhTP>
  21:   <TinhTP>
  22:     <tenTinhTP>Hai Phong</tenTinhTP>
  23:     <QuanHuyen>
  24:       <tenQuanHuyen>Le Chan</tenQuanHuyen>
  25:       <PhuongXa>
  26:         <tenPhuongXa>Cu Lai</tenPhuongXa>
  27:       </PhuongXa>
  28:     </QuanHuyen>
  29:     <QuanHuyen>
  30:       <tenQuanHuyen>Gia Dinh</tenQuanHuyen>
  31:       <PhuongXa>
  32:         <tenPhuongXa>Cam Thuong</tenPhuongXa>
  33:       </PhuongXa>
  34:       <PhuongXa>
  35:         <tenPhuongXa>Dong Quang</tenPhuongXa>
  36:       </PhuongXa>
  37:     </QuanHuyen>
  38:   </TinhTP>
  39: </DiaChi>


Sau đó chúng ta add file xml này vào Data Connections của InfoPath



Tiếp theo chúng ta xử lý các Event:ChangedEventHandler đối với 3 drop-down list



Trước hết chúng ta đăng ký các Event






   1: public void InternalStartup()
   2:        {
   3:            EventManager.FormEvents.Loading += new LoadingEventHandler(FormEvents_Loading);
   4:            EventManager.XmlEvents["/my:myFields/my:tinhTP"].Changed += new XmlChangedEventHandler(tinhTP_Changed);
   5:            EventManager.XmlEvents["/my:myFields/my:quanHuyen"].Changed += new XmlChangedEventHandler(quanHuyen_Changed);
   6:        }


Trong khi load form chúng ta binding và Tỉnh thành phố drop-Down






   1: public void FormEvents_Loading(object sender, LoadingEventArgs e)
   2:         {            
   3:             AddTinhTPs();
   4:         } 
   5:  
   6:         private void AddTinhTPs()
   7:         {           
   8:             try
   9:             { 
  10:  
  11:                 XPathNavigator navAddress = DataSources["Address"].CreateNavigator(); 
  12:  
  13:                 // Compile a standard XPath expression
  14:                 XPathExpression exprTinhTP;
  15:                 exprTinhTP = navAddress.Compile("/DiaChi/TinhTP/tenTinhTP");
  16:                 XPathNodeIterator iteratorTinhTP = navAddress.Select(exprTinhTP);
  17:                 if (iteratorTinhTP != null && iteratorTinhTP.Count >= 1)
  18:                 {
  19:                     XPathNavigator nav = this.CreateNavigator().SelectSingleNode("/my:myFields/my:TinhTPs", this.NamespaceManager);
  20:                     while (iteratorTinhTP.MoveNext())
  21:                     {
  22:                         XPathNavigator newNode = null;
  23:                         newNode = nav.Clone();
  24:                         newNode.SelectSingleNode("/my:myFields/my:TinhTPs/my:tinhTPDisplayName", this.NamespaceManager).SetValue(iteratorTinhTP.Current.Value);
  25:                         newNode.SelectSingleNode("/my:myFields/my:TinhTPs/my:tinhTPValue", this.NamespaceManager).SetValue(iteratorTinhTP.Current.Value);
  26:                         nav.InsertAfter(newNode);
  27:                         newNode = null;
  28:                     }
  29:                     nav.DeleteSelf();
  30:                     nav = null;
  31:                 }
  32:             }
  33:             catch (Exception ex)
  34:             {
  35:                 WriteLog(ex.ToString());
  36:             }
  37:         }


Xử lý Event khi select item trong Tỉnh thành phố. Lúc này chúng ta mới binding đối với Quận huyện Drop-Down list






   1: public void tinhTP_Changed(object sender, XmlEventArgs e)
   2:         {            
   3:             string selectedTinhTP = this.CreateNavigator().SelectSingleNode("/my:myFields/my:tinhTP", this.NamespaceManager).Value;
   4:             if (!string.IsNullOrEmpty(selectedTinhTP))
   5:             {
   6:                 WriteLog("tinhTP_Changed:" + selectedTinhTP + "/" + e.NewValue);
   7:                 AddQuanHuyens(selectedTinhTP);
   8:             }
   9:         }
  10:  
  11: private void AddQuanHuyens(string selectedTinhTP)
  12:         {
  13:            try
  14:            {
  15:                XPathNavigator navAddress = DataSources["Address"].CreateNavigator();
  16:                // Compile a standard XPath expression
  17:                 XPathExpression exprQuanHuyen;
  18:                 string exprXPath = "/DiaChi/TinhTP[tenTinhTP='" + selectedTinhTP + "']/QuanHuyen/tenQuanHuyen";
  19:                 exprQuanHuyen = navAddress.Compile(exprXPath);
  20:                 XPathNodeIterator iteratorQuanHuyen = navAddress.Select(exprQuanHuyen); 
  21:  
  22:                 if (iteratorQuanHuyen != null && iteratorQuanHuyen.Count >= 1)
  23:                 {
  24:                     ClearGroupNode("QuanHuyens");
  25:                     XPathNavigator nav = this.CreateNavigator().SelectSingleNode("/my:myFields/my:QuanHuyens", this.NamespaceManager);
  26:                     while (iteratorQuanHuyen.MoveNext())
  27:                     {
  28:                         XPathNavigator newNode = null;
  29:                         newNode = nav.Clone();
  30:                         newNode.SelectSingleNode("/my:myFields/my:QuanHuyens/my:quanHuyenDisplayName", this.NamespaceManager).SetValue(iteratorQuanHuyen.Current.Value);
  31:                         newNode.SelectSingleNode("/my:myFields/my:QuanHuyens/my:quanHuyenValue", this.NamespaceManager).SetValue(iteratorQuanHuyen.Current.Value);
  32:                         nav.InsertAfter(newNode);
  33:                         newNode = null;
  34:                     } 
  35:  
  36:                     nav.DeleteSelf();
  37:                     nav = null;
  38:                 }
  39:                 WriteLog("AddQuanHuyens:" + exprXPath);
  40:             }
  41:             catch (Exception ex)
  42:             {
  43:                 WriteLog(ex.ToString());
  44:             }
  45:         }


Tương tự, chúng ta xử lý cho Phường xã.



Toàn bộ source code cho Cascading Address này được đính kèm trong bài viết này, các bạn tham khảo và cho ý kiến

Thứ Năm, 14 tháng 5, 2009

WCF và nguyên lý ABC

 

A21319952F68E79E_308_0[1]

Thứ Tư, 13 tháng 5, 2009

RSS/Atom và cách tạo RSS/Atom cho website của bạn

Ngày nay RSS và Atom đã trở nên phổ biến, tuy nhiên sẽ có nhiều lập trình viên đặt câu hỏi: Làm thế nào để tạo ra RSS cho website của bạn. Là một lập trình viên tôi cũng đã từng đặt câu hỏi trên. Các bạn có thể tìm thấy bài viết "Cách Tạo RSS trong ASP.NET" trên web. Tuy nhiên, chúng ta có thể tạo RSS bằng nhiều cách khách nhau nêu phân tích sâu cấu trúc của RSS: Ví dụ như sau:

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <rss version="2.0">
   3:   <channel>
   4:     <title>RSS2.0Example</title>
   5:     <link>http://www.exampleurl.com/example/index.html</link>
   6:     <description>This is an example RSS 2.0 feed</description>
   7:     <language>en-gb</language>
   8:     <copyright>Copyright 2002, Oreilly and Associates.</copyright>
   9:     <managingEditor>example@exampleurl.com</managingEditor>
  10:     <webMaster>webmaster@exampleurl.com</webMaster>
  11:     <rating> </rating>
  12:     <pubDate>03 Apr 02 1500 GMT</pubDate>
  13:     <lastBuildDate>03 Apr 02 1500 GMT</lastBuildDate>
  14:     <docs>http://backend.userland.com/rss</docs>
  15:     <skipDays>
  16:       <day>Monday</day>
  17:     </skipDays>
  18:     <skipHours>
  19:       <hour>20</hour>
  20:     </skipHours>
  21:     <category  domain="http://www.dmoz.org">
  22:       Business/Industries/Publishing/Publishers/
  23:       Nonfiction/Business/O'Reilly_and_Associates/
  24:     </category>
  25:     <generator>NewsAggregator'o'Matic</generator>
  26:     <ttl>30</ttl>
  27:         <cloud domain="http://www.exampleurl.com" port="80" path="/RPC2"
  28:       registerProcedure="pleaseNotify" protocol="XML-RPC" />
  29:         <image>
  30:           <title>RSS2.0 Example</title>
  31:           <url>http://www.exampleurl.com/example/images/logo.gif</url>
  32:           <link>http://www.exampleurl.com/example/index.html</link>
  33:           <width>88</width>
  34:           <height>31</height>
  35:           <description>The World's Leading Technical Publisher</description>
  36:         </image>
  37:         <textInput>
  38:           <title>Search</title>
  39:           <description>Search the Archives</description>
  40:           <name>query</name>
  41:           <link>http://www.exampleurl.com/example/search.cgi</link>
  42:         </textInput>
  43:         <item>
  44:           <title>The First Item</title>
  45:           <link>http://www.exampleurl.com/example/001.html</link>
  46:           <description>This is the first item.</description>
  47:           <source url="Another">http://www.anothersite.com/index.xml">Another Site</source>
  48:           <enclosure url="http://www.exampleurl.com/example/001.mp3" length="543210" type="audio/mpeg"/>
  49:           <category domain="http://www.dmoz.org">
  50:             Business/Industries/Publishing/Publishers/
  51:             Nonfiction/Business/O'Reilly_and_Associates/
  52:           </category>
  53:           <comments>http://www.exampleurl.com/comments/001.html</comments>
  54:           <author>Ben Hammersley</author>
  55:           <pubDate>Sat, 01 Jan 2002 0:00:01 GMT</pubDate>
  56:           <guid isPermaLink="true">http://www.exampleurl.com/example/001.html</guid>
  57:         </item>
  58:         <item>
  59:           <title>The Second Item</title>
  60:           <link>http://www.exampleurl.com/example/002.html</link>
  61:           <description>This is the second item.</description>
  62:           <source url="Another">http://www.anothersite.com/index.xml">Another Site</source>
  63:           <enclosure url="http://www.exampleurl.com/example/002.mp3" length="543210" type="audio/mpeg"/>
  64:           <category domain="http://www.dmoz.org">
  65:             Business/Industries/Publishing/Publishers/
  66:             Nonfiction/Business/O'Reilly_and_Associates/
  67:           </category>
  68:           <comments>http://www.exampleurl.com/comments/002.html</comments>
  69:           <author>Ben Hammersley</author>
  70:           <pubDate>Sun, 02 Jan 2002 0:00:01 GMT</pubDate>
  71:           <guid isPermaLink="true">http://www.exampleurl.com/example/002.html</guid>
  72:         </item>
  73:         <item>
  74:           <title>The Third Item</title>
  75:           <link>http://www.exampleurl.com/example/003.html</link>
  76:           <description>This is the third item.</description>
  77:           <source url="Another">http://www.anothersite.com/index.xml">Another Site</source>
  78:           <enclosure url="http://www.exampleurl.com/example/003.mp3" length="543210" type="audio/mpeg"/>
  79:           <category domain="http://www.dmoz.org">
  80:             Business/Industries/Publishing/Publishers/
  81:             Nonfiction/Business/O'Reilly_and_Associates/
  82:           </category>
  83:           <comments>http://www.exampleurl.com/comments/003.html</comments>
  84:           <author>Ben Hammersley</author>
  85:           <pubDate>Mon, 03 Jan 2002 0:00:01 GMT</pubDate>
  86:           <guid isPermaLink="true">http://www.exampleurl.com/example/003.html</guid>
  87:         </item>
  88:       </channel>
  89: </rss>


Đây là một ví dụ về một file chứa RSS. Với ví dụ này chúng ta thấy, việc tạo RSS bản chất là tạo một tài liệu XML. Và việc sinh ra file XML này có rất nhiều cách khác nhau như: xml, javascrip, C#...Với sự hỗ trợ của LINQ ngày nay, thì việc tạo XML file càng trở nên đơn giản hơn nhiều.