implementing a simple Cross SIte collection list view webpart
Out of the box list view web part does not support lists that are contained in a different site collection. In this post I will show you how you can write a simple web part that will allow cross site collection list support.
Within the custom web part I’m leveraging ListViewByQuery control that is contained within the “Microsoft.SharePoint.WebControls” namespace in assembly “Microsoft.SharePoint.dll”
Couple of things about “ListViewByQuery” control
- you must set “List” and “Query” properties for this control
- You will get a “missing list” exception or something like that if you don’t set “ViewFields” property for the Query
- SPQuery should be instantiated with a View, otherwise you will get a blank page (If you instantiate SPQuery with a view you do not need to specify “ViewFields” property although MSDN documentation states different)
My custom web part has following properties defined
SiteUrl: if the list is in different site collection, set site collection URL
ViewName: List View Name to be used
SourceList: Source List to Query
In the overriden CreateChildControls method of web part new up an instance of “ListViewControl” and set List and Query properties and add to the controls collection. If a site url was not specified, we assume the list is contained within the current web context, also if a view name was specified through properties, we are using that when creating SPQuery object, other wise default view on the list is used.
1: protected override void CreateChildControls()
2: {
3: base.CreateChildControls();
4: SPSite site = null ;
5: SPWeb web = null ;
6: Boolean disposeSPSite = false ;
7: try
8: {
9: if (this.SourceList != string.Empty && this.SourceList != string.Empty)
10: {
11: viewByQuery = new ListViewByQuery();
12: if(this.SiteUrl != null && this.SiteUrl != string.Empty)
13: {
14: site = new SPSite(this.SiteUrl);
15: disposeSPSite = true ;
16: }
17: else
18: {
19: site = SPContext.Current.Site ;
20: }
21: web = site.OpenWeb();
22: SPList sourceList = web.Lists[this.SourceList];
23: viewByQuery.List = sourceList;
24: SPQuery query = null;
25: if (CheckIfViewExists(viewByQuery.List))
26: {
27: //use the view specified in webpart property
28: query = new SPQuery(viewByQuery.List.Views[this.ViewName]);
29: }
30: else
31: {
32: //use default view to initialized
33: query = new SPQuery(viewByQuery.List.DefaultView);
34: }
35: viewByQuery.Query = query;
36: viewByQuery.DisableFilter = this.DisableFilter;
37: viewByQuery.DisableSort = this.DisableSort;
38: this.Controls.Add(viewByQuery);
39: }
40: else
41: {
42: encodedLiteral = new EncodedLiteral();
43: encodedLiteral.Text = "This webpart is not configured.";
44: this.Controls.Add(encodedLiteral);
45: }
46: }
47: finally
48: {
49: if(disposeSPSite)
50: {
51: ((IDisposable)site).Dispose();
52: ((IDisposable)web).Dispose();
53: }
54: }
55: }
Custom Web Part Configuration View
Here is a view of the web part showing documents from document library named “Documents” contained within a different site collection
All Items view of document library named “Documents” in root site collection of the web app
<Update Date="10/10/2010">
I recently received comment about not being able to see folder, try setting the ViewAttributes property for the SPQuery object
Ex:
query.ViewAttributes = "Scope=\"Recursive\"";
</Update>
Code from web part project, if you find it useful please leave a comment here…
1: #region using statements
2: using System;
3: using System.Runtime.InteropServices;
4: using System.Web;
5: using System.Web.UI;
6: using System.Web.UI.WebControls;
7: using System.Web.UI.WebControls.WebParts;
8: using System.Xml.Serialization;
9: using System.Text;
10:
11:
12: using Microsoft.SharePoint;
13: using Microsoft.SharePoint.WebControls;
14: using Microsoft.SharePoint.WebPartPages;
15: #endregion
16:
17: namespace Foo
18: {
19: [Guid("9558189B-CD3B-481b-9B06-AE434CF47B18")]
20: public class CrossSiteCollectionListViewWebPart : System.Web.UI.WebControls.WebParts.WebPart
21: {
22: #region protected child control variable definitions
23: protected ListViewByQuery viewByQuery = null;
24: protected EncodedLiteral encodedLiteral = null;
25: #endregion
26:
27: #region webpart properties
28: /// <summary>
29: ///
30: /// </summary>
31: private string viewNameField = string.Empty;
32: [Personalizable(), WebPartStorage(Storage.Shared), WebBrowsable(),
33: WebDisplayName("View Name"), WebDescription("View Name")]
34: public string ViewName
35: {
36: get
37: {
38: return this.viewNameField;
39: }
40: set
41: {
42: this.viewNameField = value;
43: }
44: }
45: private string siteUrlField = string.Empty;
46: [Personalizable(), WebPartStorage(Storage.Shared), WebBrowsable(),
47: WebDisplayName("Site Url"), WebDescription("Site Url")]
48: public string SiteUrl
49: {
50: get
51: {
52: return this.siteUrlField;
53: }
54: set
55: {
56: this.siteUrlField = value;
57: }
58: }
59: /// <summary>
60: ///
61: /// </summary>
62: private string sourceListField = string.Empty;
63: [Personalizable(), WebPartStorage(Storage.Shared), WebBrowsable(),
64: WebDisplayName("Source List"), WebDescription("Source list to query")]
65: public string SourceList
66: {
67: get
68: {
69: return this.sourceListField;
70: }
71: set
72: {
73: this.sourceListField = value;
74: }
75: }
76: private Boolean disableFilterField = false;
77: [Personalizable(), WebPartStorage(Storage.Shared), WebBrowsable(),
78: WebDisplayName("Disable Filter"), WebDescription("Disable List Filtering")]
79: public Boolean DisableFilter
80: {
81: get
82: {
83: return disableFilterField;
84: }
85: set
86: {
87: disableFilterField = value;
88: }
89: }
90: private Boolean disableSortField = false;
91: [Personalizable(), WebPartStorage(Storage.Shared), WebBrowsable(),
92: WebDisplayName("Disable Sort"), WebDescription("Disable list sorting")]
93: public Boolean DisableSort
94: {
95: get
96: {
97: return disableSortField;
98: }
99: set
100: {
101: this.disableSortField = value;
102: }
103: }
104: #endregion
105:
106: #region overrides
107: protected override void CreateChildControls()
108: {
109: base.CreateChildControls();
110: SPSite site = null ;
111: SPWeb web = null ;
112: Boolean disposeSPSite = false ;
113: try
114: {
115: if (this.SourceList != string.Empty && this.SourceList != string.Empty)
116: {
117: viewByQuery = new ListViewByQuery();
118: if(this.SiteUrl != null && this.SiteUrl != string.Empty)
119: {
120: site = new SPSite(this.SiteUrl);
121: disposeSPSite = true ;
122: }
123: else
124: {
125: site = SPContext.Current.Site ;
126: }
127: web = site.OpenWeb();
128: SPList sourceList = web.Lists[this.SourceList];
129: viewByQuery.List = sourceList;
130: SPQuery query = null;
131: if (CheckIfViewExists(viewByQuery.List))
132: {
133: //use the view specified in webpart property
134: query = new SPQuery(viewByQuery.List.Views[this.ViewName]);
135: }
136: else
137: {
138: //use default view to initialized
139: query = new SPQuery(viewByQuery.List.DefaultView);
140: }
141: viewByQuery.Query = query;
142: viewByQuery.DisableFilter = this.DisableFilter;
143: viewByQuery.DisableSort = this.DisableSort;
144: this.Controls.Add(viewByQuery);
145: }
146: else
147: {
148: encodedLiteral = new EncodedLiteral();
149: encodedLiteral.Text = "This webpart is not configured.";
150: this.Controls.Add(encodedLiteral);
151: }
152: }
153: finally
154: {
155: if(disposeSPSite)
156: {
157: ((IDisposable)site).Dispose();
158: ((IDisposable)web).Dispose();
159: }
160: }
161: }
162: protected override void RenderContents(HtmlTextWriter writer)
163: {
164:
165: EnsureChildControls();
166: RenderChildren(writer);
167: }
168: #endregion
169:
170: #region helper methods
171: private Boolean CheckIfViewExists(SPList list)
172: {
173: Boolean ret = false;
174:
175: foreach (SPView view in list.Views)
176: {
177: if (view.Title.ToLower() == this.ViewName.ToLower())
178: {
179: ret = true;
180: }
181: }
182: return ret;
183: }
184: #endregion
185: }
186: }
Technorati Tags: sharePoint,WebParts
Comments
Anonymous
April 21, 2009
PingBack from http://microsoft-sharepoint.simplynetdev.com/implementing-a-simple-cross-site-collection-list-view-webpart/Anonymous
May 08, 2009
Nice post. Really useful. There is an another web-part called "SiteDocuments" - which can do nearly the same thing for the document libraries.Anonymous
June 03, 2009
have a list that has a column that is a "choice" field. I have selections that they can chooose from in rop down format.....and i i have added some values and default value too.I am using the list senario in meeting events list,i have to check the condition when any one uses New Item->Save and close then i have to check wheather anyone already selected some choice field for specific time,i donot want to allow others to book that choice again ,i have to show some custom message...is there any way I can read the values of choice column and check the meeting events values already booked ,then diplay som emessage that that choice is already booked message in New Form.aspx? I am using SPS2003,Designer 2007,wss 2.0. Can we do the above by using of webpart. Please help my out . Regards RaviAnonymous
July 16, 2009
It would be really useful if you could provide the baby steps on how to deploy this code. Did you use VSeWSS? Did you start with a Web part template? Can this be saved as a solution and deployed globally? Any advice appreciated.Anonymous
August 30, 2009
Hi, Your code is really helpful, but when i show the list from other site i.e other web application not same site collection, then display and edit items thows error becuase it assumes that list is in same site collection. Is there and solution to this?Anonymous
September 01, 2009
I will take a look at this and post response here Thanks, </Ram>Anonymous
September 27, 2009
Is there a way to export the listviewbyquery results to Excel? daniel.r.walker1@navy.milAnonymous
October 27, 2009
Hello Ram, I have a requirement to retrieve all the open and closed service requests from a list called Service requests. I have a web application with 2 site collections. Service requests list is in one site collection and in the second site collection i am using your web part to retrieve all the data. This does retrieves the data but the problem comes when i added 2 webparts on the same page. One for Open and second for closed service requests. I have 2 questions for you : 1 ) My requirement is to make the closed Service requests web part to be collapsed by default. When i set this in the view, i always see "Loading..."om the web part page. It never loads
- If in both open and closed service requests web parts if i use group by caluse in the view , and i try to expand and collapse them in the web part. It never works. Like for example i have 2 webparts on same page. If i try to expand/collapse the second web part it always collapses/expands for the first webpart. which is weird. Do you have any thoughts or suggestions on this. I appreciate your help. Thanks.
Anonymous
January 08, 2010
Excellent Post! You saved me a lot of development time.Anonymous
February 03, 2010
Thanks for the code, works brilliantly! I'm trying to create a web part which uses the same list and site but different views. When i try to hard code the list name i get an unhandled exception...any ideas?Anonymous
February 16, 2010
hi Ram Thanq very much it was very help fulAnonymous
March 22, 2010
Hello Ram, thank you for your great blog! Your solution is great, however, I am having the problem that if I use the Group By feature in the view, the cross-site collection list view webpart will not expand the selection. Is there a problem with adding the required javascript files? (Ajax issue). Could you help me out? Thanks again. MartinAnonymous
April 09, 2010
Excellent. Work -- I've been looking a different solutions for this problem and yours is definitely the best. Now I need to figure out a way to security trim based on a query of the site directory. Any ideas?Anonymous
April 09, 2010
Hello Ram, I am trying to find the ways to deploy this code, can you give the steps. I have visual studion 2008 professional edition with sharepoin extensions, i am seeing that when ever i deploy the webpart ( simple hello webpart) the process of creting wsp and adding to gac and activating the feature is all handling by Visual studio as I am working on the sharepoint server but when i try to add the webpart i am getting the message saying that i need to add the safecontrol.. is it not handled by visual studio.. do i need to add anything to xml files to achieve this. right now i just build and click on deploy.. please advice.. much appericiate your help. thanks.Anonymous
April 09, 2010
Jay: Not sure if I understand your scenario well, why do you need to security trim based on site directory query? Naresh: WSP Deployment should have done this automatically, how ever you can manually edit the solution manifest and make sure there is a safecontrol entry for your webpart <SafeControl Assembly = "{replace with webpart assembly" Namespace = "{replace with your namespace}" Safe = "TRUE" | "FALSE" TypeName = "{replace}"> </SafeControl>Anonymous
April 26, 2010
Hi! It works!!, BUT it doesn't seem to work when there are folders inside of the list. When I click on a folder, the page that contains the list appears and nothing else happens. Is there a workaround to fix this issue ? Thank you !Anonymous
May 06, 2010
This works great until you put a Folder object in the Document Library. This is proving to be quite a tricky issue, clicking a folder sends you the the Document Library View page. This would need to be modified to post back to itself, which I've got working, but the query of a Folders contents appears to be a common problem that I'm haven't yet found an answer to. Any ideas?