A few days back, i was unable to import user profiles, after our development server crashed and fortunately we restored it using the last known back-up of the Virtual machine. All of a sudden our user profiles import and search crawling and indexing services stopped abruptly, throwing a nasty "An indexer is not assigned to the Shared Services Provider 'SharedServices1' error.
Luckily i found a solution for the same:
a. Log in to Central Administration
b. Select your Shared Services provider and choose "Edit Properties" from the drop-down context menu
c. Configure your Index server and it works like a charm...
Mehul Bhuva is an AI and Data Platform Engineer bringing two decades of specialized experience across Microsoft's technology ecosystem. His proficiency spans Azure, Databricks, Microsoft AI Foundry, Azure Data Factory, Blazor/Angular frameworks, Powershell and Power BI.
Saturday, February 7, 2009
Sunday, January 25, 2009
Case Study - ECM for Enterprise wide Sharepoint Intranet Collaboration Portal
We recently completed development of my company's Collaboration Intranet Portal, here is a small case-study of MOSS features we have used and customizations we have done during the development phase:
1. Use of default Publishing features: We created a site collection using Collaboration Publishing Portal site template, in that way we got what we wanted for ECM including Page Publishing with Approval mechanism.
2. Site Structure and Architecture: We had a single site collection with various internal departments as Sites under One site collection like : we had Home as the top level site and then HR, Finance, Administration, Business Units etc as our sub-sites within the site collection. We had a single server farm, one dedicated search server and one SSP configured.
We had separate Virtual machines configured for Development, Content Management and Production environment respectively with WSS SP 1 and MOSS SP 1. We had identified a few Content Managers from within the respective units, who would maintain their respective sites for managing/uploading content in lists/libraries.
3. Capacity Planning: We had a Cord Core processor with sufficient hard-disk and 4 GB RAM, our capacity planning was based on the fact that we had a target audience of 3000 users within the organization.
4. Use of custom Master page, custom Page Layouts and custom styles: We actually created a copy of default.master, a copy of Page Layout from Blank Web Part page and a copy of Core.css from Style Library using SharePoint Designer, after creating copies of each of them we restructured the entire master page and added some new styles in our custom style sheet, we had to hide certain Content Placeholders from Master page(you should not delete these placeholders, instead place them all in an control with visibility as hidden to avoid errors), we then added a new Left Web part Zone to our Custom Page Layout, all using SharePoint Designer
But doing all the above mentioned customizations using SPD was not a viable option as all the pages would then become un-ghosted (customized) and everything would be then stored into SharePoint Content Databases, instead we copied all the three files we developed with SPD into the file system and deployed it as a feature using WSP builder, so we could get both the benefit of Visual design using SPD and Ghosting (un-customization). So we now have our custom master page, custom page layout and custom style sheet on the file system, making it more scalable across farms, as all of them have been deployed as features, we also have them under our source control now.
5. Use of .NET User Controls: We used a lot of pure .NET user controls within the custom master page, for e.g. the organization wanted to display names of its employees having their birthdays on that day, in a dynamic ticker which would change each day, the birthday data was exported from excel to SharePoint list using the Excel Add-In for MOSS 2007, click on the link to download, http://www.microsoft.com/downloads/details.aspx?familyid=25836e52-1892-4e17-ac08-5df13cfc5295&displaylang=en
We then used a calculated field to determine employee birthdays as on Today. Similarly, we also had a rolling ticker for News, Events and Announcements from SharePoint lists across all the sites in the site collection; we had to use impersonation due to some security concerns in accessing lists across subsites.
Similarly, we had to roll thumbnails of pictures from the Site Collection Image Gallery on the top-level site, when clicked the enlarged images would appear as a lite box pop-up. We could have used J-Query too, may be next time.
The beauty of using User Controls in master page is that we could maintain them without having to customize the master page, the hassle of upgrading the WSP file, redeploying the feature is no longer required, in case any of the user control file changes.
We deployed .ascx files in the Control Templates folder of the 12 hive structure, then deployed the DLL in inetpub\wwwroot\\bin, we also had to register the DLL in GAC
To create User Controls with MOSS, read this excellent post: http://www.helloitsliam.com/archive/2008/01/21/sharepoint-%E2%80%93-user-control-in-master-page-page-footer.aspx
6. List Items as Pop-ups: We also made a .aspx page which will accept List Item Id to be displayed, List Name and Column Name as query string parameters, this was deployed in the LAYOUTS folder of the 12 hive structure, it meant that it will now be accessible to any site within the site collection due to the virtual directory _layouts which is mapped to the physical folder LAYOUTS, so if I have to call the .aspx page from the HR sub-site, I would call it in the following way: /HR/_layouts/ShowListDescription.aspx?ItemId=1&ListName=NewsEvents&ColumnName=NewsDescription
We used to link the .aspx page as a Read More… pop-up in the List View web part, so that it could show the description/details of that particular list item in a pop-up window.
7. Daily Back Up and Restore: Since, we had a separate Content Managers Environment for uploading data into lists/libraries, we would actually perform back-up and restore drills each day to move updated content from Content manager’s environment to Production environment. We created back-up and restore batch scripts, it would have to be run manually each day by a dedicated Administrator as he had to copy .bak files and move it across the server and then restore. Later on we found that this could have been achieved without manual intervention using Content Deployment Jobs, to download this white paper, visit: http://technet.microsoft.com/enus/library/cc627268.aspx
8. Third party web parts: We used various free third-party web parts like the Quick
a. Surveys web part for Surveys & Polls (http://code.msdn.microsoft.com/QuickSurveys)
b. Zone Tabs web part to show web parts in a tabbed manner (http://code.msdn.microsoft.com/zonetabs)
c. RSS Feed Reader web part from CodePlex: http://www.codeplex.com/FeedReader/Release/ProjectReleases.aspx?ReleaseId=19830
We also customized the existing Content Query Web part to include URL’s from Link List, here is an excellent article: http://www.helloitsliam.com/archive/2007/11/06/moss2007-–-link-lists-and-the-content-query-web-part.aspx
9. Use of Visual Studio workflows: We had to pick up email addresses from a master list based on the site context and send an Email alert to the appropriate contact, whenever a Suggestion/Feedback is entered from the portal; we used Visual Studio Workflows and deployed it as a SharePoint feature.
10. Search Scopes: We created context based Search Scopes like HR, Finance, Admin, Purchase using Central Administration and then added them to our Site Collection using Search Scopes setting at the top level site collection.
11. Stress Testing Tool: We used Microsoft Stress Testing tool in order to load test concurrent users, we created 100 dummy users and test scripts for all the pages, load tested our application for about 12 hours, we found RPS rate was good and the application didn't even crashed once, when the concurrent stress testing was going on.
All throughout i was reading Andrew Connel's book on Web Content Management for Sharepoint, (Go to Andrew Connels bookshelf) Heather Solomon’s blog for Custom master pages (http://www.heathersolomon.com/blog/) During my development phase, i got some help from John Holliday in relation to Disposing Sharepoint objects while using Sharepoint API. Liam Cleary's wonderful posts also help me profoundly.
1. Use of default Publishing features: We created a site collection using Collaboration Publishing Portal site template, in that way we got what we wanted for ECM including Page Publishing with Approval mechanism.
2. Site Structure and Architecture: We had a single site collection with various internal departments as Sites under One site collection like : we had Home as the top level site and then HR, Finance, Administration, Business Units etc as our sub-sites within the site collection. We had a single server farm, one dedicated search server and one SSP configured.
We had separate Virtual machines configured for Development, Content Management and Production environment respectively with WSS SP 1 and MOSS SP 1. We had identified a few Content Managers from within the respective units, who would maintain their respective sites for managing/uploading content in lists/libraries.
3. Capacity Planning: We had a Cord Core processor with sufficient hard-disk and 4 GB RAM, our capacity planning was based on the fact that we had a target audience of 3000 users within the organization.
4. Use of custom Master page, custom Page Layouts and custom styles: We actually created a copy of default.master, a copy of Page Layout from Blank Web Part page and a copy of Core.css from Style Library using SharePoint Designer, after creating copies of each of them we restructured the entire master page and added some new styles in our custom style sheet, we had to hide certain Content Placeholders from Master page(you should not delete these placeholders, instead place them all in an control with visibility as hidden to avoid errors), we then added a new Left Web part Zone to our Custom Page Layout, all using SharePoint Designer
But doing all the above mentioned customizations using SPD was not a viable option as all the pages would then become un-ghosted (customized) and everything would be then stored into SharePoint Content Databases, instead we copied all the three files we developed with SPD into the file system and deployed it as a feature using WSP builder, so we could get both the benefit of Visual design using SPD and Ghosting (un-customization). So we now have our custom master page, custom page layout and custom style sheet on the file system, making it more scalable across farms, as all of them have been deployed as features, we also have them under our source control now.
5. Use of .NET User Controls: We used a lot of pure .NET user controls within the custom master page, for e.g. the organization wanted to display names of its employees having their birthdays on that day, in a dynamic ticker which would change each day, the birthday data was exported from excel to SharePoint list using the Excel Add-In for MOSS 2007, click on the link to download, http://www.microsoft.com/downloads/details.aspx?familyid=25836e52-1892-4e17-ac08-5df13cfc5295&displaylang=en
We then used a calculated field to determine employee birthdays as on Today. Similarly, we also had a rolling ticker for News, Events and Announcements from SharePoint lists across all the sites in the site collection; we had to use impersonation due to some security concerns in accessing lists across subsites.
Similarly, we had to roll thumbnails of pictures from the Site Collection Image Gallery on the top-level site, when clicked the enlarged images would appear as a lite box pop-up. We could have used J-Query too, may be next time.
The beauty of using User Controls in master page is that we could maintain them without having to customize the master page, the hassle of upgrading the WSP file, redeploying the feature is no longer required, in case any of the user control file changes.
We deployed .ascx files in the Control Templates folder of the 12 hive structure, then deployed the DLL in inetpub\wwwroot\
To create User Controls with MOSS, read this excellent post: http://www.helloitsliam.com/archive/2008/01/21/sharepoint-%E2%80%93-user-control-in-master-page-page-footer.aspx
6. List Items as Pop-ups: We also made a .aspx page which will accept List Item Id to be displayed, List Name and Column Name as query string parameters, this was deployed in the LAYOUTS folder of the 12 hive structure, it meant that it will now be accessible to any site within the site collection due to the virtual directory _layouts which is mapped to the physical folder LAYOUTS, so if I have to call the .aspx page from the HR sub-site, I would call it in the following way: /HR/_layouts/ShowListDescription.aspx?ItemId=1&ListName=NewsEvents&ColumnName=NewsDescription
We used to link the .aspx page as a Read More… pop-up in the List View web part, so that it could show the description/details of that particular list item in a pop-up window.
7. Daily Back Up and Restore: Since, we had a separate Content Managers Environment for uploading data into lists/libraries, we would actually perform back-up and restore drills each day to move updated content from Content manager’s environment to Production environment. We created back-up and restore batch scripts, it would have to be run manually each day by a dedicated Administrator as he had to copy .bak files and move it across the server and then restore. Later on we found that this could have been achieved without manual intervention using Content Deployment Jobs, to download this white paper, visit: http://technet.microsoft.com/enus/library/cc627268.aspx
8. Third party web parts: We used various free third-party web parts like the Quick
a. Surveys web part for Surveys & Polls (http://code.msdn.microsoft.com/QuickSurveys)
b. Zone Tabs web part to show web parts in a tabbed manner (http://code.msdn.microsoft.com/zonetabs)
c. RSS Feed Reader web part from CodePlex: http://www.codeplex.com/FeedReader/Release/ProjectReleases.aspx?ReleaseId=19830
We also customized the existing Content Query Web part to include URL’s from Link List, here is an excellent article: http://www.helloitsliam.com/archive/2007/11/06/moss2007-–-link-lists-and-the-content-query-web-part.aspx
9. Use of Visual Studio workflows: We had to pick up email addresses from a master list based on the site context and send an Email alert to the appropriate contact, whenever a Suggestion/Feedback is entered from the portal; we used Visual Studio Workflows and deployed it as a SharePoint feature.
10. Search Scopes: We created context based Search Scopes like HR, Finance, Admin, Purchase using Central Administration and then added them to our Site Collection using Search Scopes setting at the top level site collection.
11. Stress Testing Tool: We used Microsoft Stress Testing tool in order to load test concurrent users, we created 100 dummy users and test scripts for all the pages, load tested our application for about 12 hours, we found RPS rate was good and the application didn't even crashed once, when the concurrent stress testing was going on.
All throughout i was reading Andrew Connel's book on Web Content Management for Sharepoint, (Go to Andrew Connels bookshelf) Heather Solomon’s blog for Custom master pages (http://www.heathersolomon.com/blog/) During my development phase, i got some help from John Holliday in relation to Disposing Sharepoint objects while using Sharepoint API. Liam Cleary's wonderful posts also help me profoundly.
Sunday, December 21, 2008
Best Practices disposing Sharepoint objects - Reference Guide
Frequently developers use the Sharepoint object model either to read or write data into Share point database via Lists/Libraries. Here comes the need to dispose Sharepoint objects, even though they are created as managed objects, these objects use unmanaged code and memory to perform a majority of their work.
Because the smaller managed part of the object does not put memory pressure on the garbage collector, the garbage collector does not release the object from memory in a timely manner. The object's use of a large amount of unmanaged memory can cause some of the unusual behaviors described as follows:
Unusual behaviors mentioned above occur when Sharepoint objects are not disposed off properly or explicitly by the devlopers. Here is a reference guide on Sharepoint Coding best practices with relevant scenarios and examples of each type:
Three techniques to ensure that your objects get disposed properly:
Thankfully Microsoft has recently launched Sharepoint Dispose Checker utility. It will ensure that you have properly disposed objects so that you aren't consuming more memory. All developers should run this utility after they use Sharepoint object model. Click here to download SPDispose Utility.
NOTE : This post is applicable for both SharePoint 2010 and SharePoint 2007
Best Practice #1: Use the Using Clause for all Sharepoint objects that implement the IDisposable interface
•SPContext.Current.Web
•SPContext.Site
•SPContext.Web
•SPControl.GetContextWeb(..)
•SPControl.GetContextSite(..)
•SPFeatureReceiverProperties.Feature.Parent
•SPItemEventProperties.ListItem.Web
•SPList.BreakRoleInheritance()
◦Do not call list.ParentWeb.Dispose()
•SPListEventProperties.Web
•SPListEventProperties.List.Web
•SPSite.RootWeb
◦Problems may occur when SPContext.Web has equality to the SPContext.Web.. make sure you dispose of SPSite and it will cleanup sub webs automatically
•SPSite.LockIssue
•SPSite.Owner
•SPSite.SecondaryContact
•SPWeb.ParentWeb
•SPWebEventProperties.Web
Changes:
•Microsoft.SharePoint.WebControls.SiteAdminsitrationSelector.CurrentItem
◦When used with WSS 3.0 you must call Dispose(), with SharePoint Foundation 2010 you don’t.
•Event Receivers and properties.OpenWeb()
◦WSS 3.0: When you call properties.OpenWeb() the returned SPWeb will need to call Dispose()
◦SharePoint Foundation 2010: Use the newly introduced SPItemEventProperties.Web property instead of SPItemEventProperties.OpenWeb() for better performance and to avoid the need to call Dispose().
Because the smaller managed part of the object does not put memory pressure on the garbage collector, the garbage collector does not release the object from memory in a timely manner. The object's use of a large amount of unmanaged memory can cause some of the unusual behaviors described as follows:
- Frequent recycles of the Microsoft Windows SharePoint Services application pool, especially during peak usage
- Application crashes that appear as heap corruption in the debugger
- High memory use for Microsoft Internet Information Services (IIS) worker processes
- Poor system and application performance
Unusual behaviors mentioned above occur when Sharepoint objects are not disposed off properly or explicitly by the devlopers. Here is a reference guide on Sharepoint Coding best practices with relevant scenarios and examples of each type:
Three techniques to ensure that your objects get disposed properly:
- Dispose method
- using clause
- try, catch, and finally blocks
Thankfully Microsoft has recently launched Sharepoint Dispose Checker utility. It will ensure that you have properly disposed objects so that you aren't consuming more memory. All developers should run this utility after they use Sharepoint object model. Click here to download SPDispose Utility.
NOTE : This post is applicable for both SharePoint 2010 and SharePoint 2007
Best Practice #1: Use the Using Clause for all Sharepoint objects that implement the IDisposable interface
C# Coding snippet String str; using(SPSite oSPsite = new SPSite("http://server")) { using(SPWeb oSPWeb = oSPSite.OpenWeb()) { str = oSPWeb.Title; str = oSPWeb.Url; } } Best Practice #2: Use the try/catch/finally blocks. When you use try blocks, it is important to add a finally block to ensure that all objects are disposed off properly: C# Coding snippet String str; SPSite oSPSite = null; SPWeb oSPWeb = null; try { oSPSite = new SPSite("http://server"); oSPWeb = oSPSite.OpenWeb(..); str = oSPWeb.Title; } catch(Exception e) { } finally { if (oSPWeb != null) oSPWeb.Dispose(); if (oSPSite != null) oSPSite.Dispose(); } Best Practice #3: Using Response.Redirect in the try block will never execute the finally block, so it is important, to dispose off all objects before the redirection occurs: C# Coding snippet String str; SPSite oSPSite = null; SPWeb oSPWeb = null; bool bDoRedirection = true; try { oSPSite = new SPSite("http://server"); oSPWeb = oSPSite.OpenWeb(..); str = oSPWeb.Title; if(bDoRedirection) { if (oSPWeb != null) oSPWeb.Dispose(); if (oSPSite != null) oSPSite.Dispose(); Response.Redirect("newpage.aspx"); } } catch(Exception e) { } finally { if (oSPWeb != null) oSPWeb.Dispose(); if (oSPSite != null) oSPSite.Dispose(); } Best Practice #4: Whenever you create an object with a new operation, the creating application must dispose it off C# Coding snippet SPSite oSPSite = new SPSite("http://server"); ... additional processing on SPSite ... oSPSite.Dispose(); alternatively, this is a better approach C# Coding snippet using(SPSite oSPSite = new SPSite("http://server")) { ... additional processing on SPSite ... } Best Practice #5: For Site.OpenWeb method, you need to dispose it off explicitly. C# Coding snippet String str; SPSite oSPSite = new SPSite("http://server"); SPWeb oSPWeb = oSPSite.OpenWeb(); str = oSPWeb.Title; str = oSPWeb.Url; ... additional processing on SPWeb ... oSPWeb.Dispose(); oSPSite.Dispose(); Alternatively you may use the Using clause too for better readibility and automatic disposition of objects: C# Coding snippet String str; using(SPSite oSPSite = new SPSite("http://server")) { using(SPWeb oSPWeb = oSPSite.OpenWeb()) { str = oSPWeb.Title; str = oSPWeb.Url; ... additional processing on SPWeb ... } } Best Practice #6: An exception to the rule is that One should not explicitly dispose SPSite.RootWeb, as it is automatically disposed off. Similary one should not explicity dispose SPContext.Current.Site and SPContext.Current.Web as they are handles automatically by Sharepoint and .NET framework. C# Bad Coding Practice Snippet: void SPContextBADPractice() { SPSite siteCollection = SPContext.Current.Site; siteCollection.Dispose(); // DO NOT DO THIS SPWeb web = SPContext.Current.Web; web.Dispose(); // DO NOT DO THIS } C# Good Coding Practice Snippet: void SPContextBestPractice() { SPSite siteCollection = SPContext.Current.Site; SPWeb web = SPContext.Current.Web; // Do NOT call Dispose() }
Best Practice #7: SPControl.GetContextSite(Context) and GetContextWeb(Context) return SPSite and SPWeb respectively, they do not need an explicit call to Dispose(), they will be disposed automatically C# Bad Coding Practice Snippet: void SPControlBADPractice() { SPSite siteCollection = SPControl.GetContextSite(Context); siteCollection.Dispose(); // DO NOT DO THIS SPWeb web = SPControl.GetContextWeb(Context); web.Dispose(); // DO NOT DO THIS } C# Good Coding Practice Snippet: void SPControlBestPractice() { SPSite siteCollection = SPControl.GetContextSite(Context); SPWeb web = SPControl.GetContextWeb(Context); // Do NOT call Dispose() } Best Practice #8: SPWeb.ParentWeb returns SPWeb, and needs to be disposed off explicitly using either Dispose() or the using clause C# Bad Coding Practice Snippet: void ParentWebLeak() { using (SPSite siteCollection = new SPSite("http://moss")) { using (SPWeb outerWeb = siteCollection.OpenWeb()) { SPWeb parentWeb = outerWeb.ParentWeb; // Internal reference to SPWeb parentWeb string sTitle = parentWeb.Title; string sUrl = parentWeb.Url; // SPWeb object parentWeb leaked } // SPWeb object outerWeb.Dispose() automatically called } // SPSite object siteCollection.Dispose() automatically called } C# Good Coding Practice Snippet: void ParentWebBestPractice() { using (SPSite siteCollection = new SPSite("http://moss")) { using (SPWeb outerWeb = siteCollection.OpenWeb()) { using (SPWeb parentWeb = outerWeb.ParentWeb) // Internal reference to SPWeb parentWeb { string sTitle = parentWeb.Title; string sUrl = parentWeb.Url; } // SPWeb object parentWeb.Dispose() automatically called } // SPWeb object outerWeb.Dispose() automatically called } // SPSite object siteCollection.Dispose() automatically called } Best Practice #9: SPWeb.Webs returns an SPWeb object, practically used in drilling down sub-sites within a Site C# Bad Coding Practice Snippet: void WebsLeak() { using (SPSite siteCollection = new SPSite("http://moss")) { using (SPWeb outerWeb = siteCollection.OpenWeb()) { foreach (SPWeb innerWeb in outerWeb.Webs) { // SPWeb innerWeb leak } } // SPWeb object outerWeb.Dispose() automatically called } // SPSite object siteCollection.Dispose() automatically called } C# Good Coding Practice Snippet: void WebsBestPractice() { using (SPSite siteCollection = new SPSite("http://moss")) { using (SPWeb outerWeb = siteCollection.OpenWeb()) { foreach (SPWeb innerWeb in outerWeb.Webs) { innerWeb.Dispose(); } } // SPWeb object outerWeb.Dispose() automatically called } // SPSite object siteCollection.Dispose() automatically called } Best Practice #10: AllWebs[] Indexer returns SPWeb object that needs to be disposed to avoid aggregation of memory which can lead to memory pressure when running on a site collection with large number of sub sites. Practically used in Enumerating or iterating all webs in a site collection. C# Bad Coding Practice Snippet: void AllWebsForEachLeakBestPractices() { using (SPSite siteCollection = new SPSite("http://moss")) { using (SPWeb outerWeb = siteCollection.OpenWeb()) { foreach (SPWeb innerWeb in siteCollection.AllWebs) { // Explicit Dispose must be called to avoid aggregation of memory } } // SPWeb object outerWeb.Dispose() automatically called } // SPSite object siteCollection.Dispose() automatically called } C# Good Coding Practice Snippet: void AllWebsForEachLeakBestPractices() { using (SPSite siteCollection = new SPSite("http://moss")) { using (SPWeb outerWeb = siteCollection.OpenWeb()) { foreach (SPWeb innerWeb in siteCollection.AllWebs) { innerWeb.Dispose(); // Explicit Dispose must be called to avoid aggregation of memory } } // SPWeb object outerWeb.Dispose() automatically called } // SPSite object siteCollection.Dispose() automatically called } C# Bad Coding Practice Snippet: void AllWebsIndexerLeak() { using (SPSite siteCollection = new SPSite("http://moss")) { SPWeb web = siteCollection.AllWebs[0]; // SPWeb web leaked } // SPSite object siteCollection.Dispose() automatically called } C# Good Coding Practice Snippet: void AllWebsIndexerBestPractice() { using (SPSite siteCollection = new SPSite("http://moss")) { using (SPWeb web = siteCollection.AllWebs[0]) { } // SPWeb object web.Dispose() automatically called } // SPSite object siteCollection.Dispose() automatically called } Best Practice #11: AllWebs.Add() returns a instance of SPWeb object which needs to be disposed. C# Bad Coding Practice Snippet: void AllWebsAddLeak() { using (SPSite siteCollection = new SPSite("http://moss")) { SPWeb web = siteCollection.AllWebs.Add("site-relative URL"); // SPWeb web Leaked } // SPSite object siteCollection.Dispose() automatically called } C# Good Coding Practice Snippet: void AllWebsAddBestPractice() { using (SPSite siteCollection = new SPSite("http://moss")) { using (SPWeb web = siteCollection.AllWebs.Add("site-relative URL")) { } // SPWeb object web.Dispose() automatically called } // SPSite object siteCollection.Dispose() automatically called } Best Practice #12: OpenWeb() returns a SPWeb object which needs to be disposed. C# Bad Coding Practice Snippet: void OpenWebLeak() { using (SPWeb web = new SPSite(SPContext.Current.Web.Url).OpenWeb()) { // SPSite leaked ! } // SPWeb object web.Dispose() automatically called } C# Good Coding Practice Snippet: void OpenWebBestPractice() { using (SPSite siteCollection = new SPSite("http://moss")) { using (SPWeb web = siteCollection.OpenWeb()) { } // SPWeb object web.Dispose() automatically called } // SPSite object siteCollection.Dispose() automatically called } Best Practice #13:new SPSite() - Instantiating SPSite objects with the new operator needs to be disposed. C# Bad Coding Practice Snippet: void CreatingSPSiteLeak() { SPSite siteCollection = new SPSite("http://moss"); // siteCollection leaked } C# Good Coding Practice Snippet: void CreatingSPSiteExplicitDisposeBestPractice() { SPSite siteCollection = new SPSite("http://moss"); siteCollection.Dispose(); } void CreatingSPSiteWithAutomaticDisposeBestPractice() { using (SPSite siteCollection = new SPSite("http://moss")) { } // SPSite object siteCollection.Dispose() automatically called } Do Not Dispose Guidance for SharePoint 2010 & 2007:(Updated on 23/2/2011):
Do not dispose the following listed objects explicitly:
•SPContext.Current.Site
•SPContext.Current.Web
•SPContext.Site
•SPContext.Web
•SPControl.GetContextWeb(..)
•SPControl.GetContextSite(..)
•SPFeatureReceiverProperties.Feature.Parent
•SPItemEventProperties.ListItem.Web
•SPList.BreakRoleInheritance()
◦Do not call list.ParentWeb.Dispose()
•SPListEventProperties.Web
•SPListEventProperties.List.Web
•SPSite.RootWeb
◦Problems may occur when SPContext.Web has equality to the SPContext.Web.. make sure you dispose of SPSite and it will cleanup sub webs automatically
•SPSite.LockIssue
•SPSite.Owner
•SPSite.SecondaryContact
•SPWeb.ParentWeb
•SPWebEventProperties.Web
Changes:
•Microsoft.SharePoint.WebControls.SiteAdminsitrationSelector.CurrentItem
◦When used with WSS 3.0 you must call Dispose(), with SharePoint Foundation 2010 you don’t.
•Event Receivers and properties.OpenWeb()
◦WSS 3.0: When you call properties.OpenWeb() the returned SPWeb will need to call Dispose()
◦SharePoint Foundation 2010: Use the newly introduced SPItemEventProperties.Web property instead of SPItemEventProperties.OpenWeb() for better performance and to avoid the need to call Dispose().
Sources: Compiled from MSDN and Roger Lamb's blog site If you find the Coding practices helpfull, please drop in your valuable comments...
Sunday, December 14, 2008
SQL Exception while applying WSS Service Pack 1
Its been a long busy month, actually i am working on our company's Intranet portal, its an end-to-end implementation, so we started right from scratch and iteration 1 is about to complete and we are nearing the virgin roll-out.
I was actually applying the WSS Service Pack 1 on our Test environment and it bombed the site, luckily i had taken the full back-up of my site collection with Content database using stsadm, (click here for more information how to take back-ups and restore the entire site collection using STSADM utility)
Immediately as i was applying the WSS 3.0 SP 1 update, the configuration wizard threw this nasty error :
An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
I tried out the following tricks (Source: MSDN)
Important These steps may increase your security risk. These steps may also make your computer or your network more vulnerable to attack by malicious users or by malicious software such as viruses. We recommend the process that this article describes to enable programs to operate as they are designed to, or to implement specific program capabilities. Before you make these changes, we recommend that you evaluate the risks that are associated with implementing this process in your particular environment. If you choose to implement this process, take any appropriate additional steps to help protect your system. We recommend that you use this process only if you really require this process.
If you are running a firewall on the computer that is running SQL Server 2005, external connections to SQL Server 2005 will be blocked unless SQL Server 2005 and the SQL Server Browser service can communicate through the firewall. You must create an exception for each instance of SQL Server 2005 that you want to accept remote connections and an exception for the SQL Server Browser service.
SQL Server 2005 uses an instance ID as part of the path when you install its program files. To create an exception for each instance of SQL Server, you must identify the correct instance ID. To obtain an instance ID, follow these steps:
.
I checked the Event Viewer and it told me something else in addition to above,
The reason I get the errors is that the content databases are not at the same version as the application files causing an inability for SharePoint to read the database. Fortunately, you can solve this by running a nice little stsadm command:
so here is what i did,
went to the Command prompt mode, typed the path of the12 Hive, i.e : cd C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN), then gave the following command,
stsadm.exe -o upgrade -forceupgrade -inplace
After Operation successfull completed message, Do an iisreset
Everything started worked beautifully like before. It was another gruilling day of the already hectic month, i immediately made up my mind on writing this article, so as to save my readers from hours of googling and needless stress.
In case, your issue is not resolved, try this: http://support.microsoft.com/kb/934838/en-us
I was actually applying the WSS Service Pack 1 on our Test environment and it bombed the site, luckily i had taken the full back-up of my site collection with Content database using stsadm, (click here for more information how to take back-ups and restore the entire site collection using STSADM utility)
Immediately as i was applying the WSS 3.0 SP 1 update, the configuration wizard threw this nasty error :
An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
I tried out the following tricks (Source: MSDN)
Enable remote connections for SQL Server 2005 Express or SQL Server 2005 Developer Edition
- Click Start, point to Programs, point to Microsoft SQL Server 2005, point to Configuration Tools, and then click SQL Server Surface Area Configuration.
- On the SQL Server 2005 Surface Area Configuration page, click Surface Area Configuration for Services and Connections.
- On the Surface Area Configuration for Services and Connections page, expand Database Engine, click Remote Connections, click Local and remote connections, click the appropriate protocol to enable for your environment, and then click Apply.
Note Click OK when you receive the following message:Changes to Connection Settings will not take effect until you restart the Database Engine service. - On the Surface Area Configuration for Services and Connections page, expand Database Engine, click Service, click Stop, wait until the MSSQLSERVER service stops, and then click Start to restart the MSSQLSERVER service.
Enable the SQL Server Browser service
If you are running SQL Server 2005 by using an instance name and you are not using a specific TCP/IP port number in your connection string, you must enable the SQL Server Browser service to allow for remote connections. For example, SQL Server 2005 Express is installed with a default instance name of Computer Name\SQLEXPRESS. You are only required to enable the SQL Server Browser service one time, regardless of how many instances of SQL Server 2005 you are running. To enable the SQL Server Browser service, follow these steps.Important These steps may increase your security risk. These steps may also make your computer or your network more vulnerable to attack by malicious users or by malicious software such as viruses. We recommend the process that this article describes to enable programs to operate as they are designed to, or to implement specific program capabilities. Before you make these changes, we recommend that you evaluate the risks that are associated with implementing this process in your particular environment. If you choose to implement this process, take any appropriate additional steps to help protect your system. We recommend that you use this process only if you really require this process.
- Click Start, point to Programs, point to Microsoft SQL Server 2005, point to Configuration Tools, and then click SQL Server Surface Area Configuration.
- On the SQL Server 2005 Surface Area Configuration page, click Surface Area Configuration for Services and Connections.
- On the Surface Area Configuration for Services and Connections page, click SQL Server Browser, click Automatic for Startup type, and then click Apply.
Note When you click the Automatic option, the SQL Server Browser service starts automatically every time that you start Microsoft Windows. - Click Start, and then click OK.
- SQL Server Browser Service
- Connecting to the SQL Server Database Engine
- Client Network Configuration
Create exceptions in Windows Firewall
These steps apply to the version of Windows Firewall that is included in Windows XP Service Pack 2 (SP2) and in Windows Server 2003. If you are using a different firewall system, see your firewall documentation for more information.If you are running a firewall on the computer that is running SQL Server 2005, external connections to SQL Server 2005 will be blocked unless SQL Server 2005 and the SQL Server Browser service can communicate through the firewall. You must create an exception for each instance of SQL Server 2005 that you want to accept remote connections and an exception for the SQL Server Browser service.
SQL Server 2005 uses an instance ID as part of the path when you install its program files. To create an exception for each instance of SQL Server, you must identify the correct instance ID. To obtain an instance ID, follow these steps:
- Click Start, point to Programs, point to Microsoft SQL Server 2005, point to Configuration Tools, and then click SQL Server Configuration Manager.
- In SQL Server Configuration Manager, click the SQL Server Browser service in the right pane, right-click the instance name in the main window, and then click Properties.
- On the SQL Server Browser Properties page, click the Advanced tab, locate the instance ID in the property list, and then click OK.
Create an exception for SQL Server 2005 in Windows Firewall
To create an exception for SQL Server 2005 in Windows Firewall, follow these steps:- In Windows Firewall, click the Exceptions tab, and then click Add Program.
- In the Add a Program window, click Browse.
- Click the C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Binn\sqlservr.exe executable program, click Open, and then click OK.
Note The path may be different depending on where SQL Server 2005 is installed. MSSQL.1 is a placeholder for the instance ID that you obtained in step 3 of the previous procedure. - Repeat steps 1 through 3 for each instance of SQL Server 2005 that needs an exception.
Create an exception for the SQL Server Browser service in Windows Firewall
To create an exception for the SQL Server Browser service in Windows Firewall, follow these steps:- In Windows Firewall, click the Exceptions tab, and then click Add Program.
- In the Add a Program window, click Browse.
- Click the C:\Program Files\Microsoft SQL Server\90\Shared\sqlbrowser.exe executable program, click Open, and then click OK.
Note The path may be different depending on where SQL Server 2005 is installed See the actual implementation of the same by Pinal Dave at: http://blog.sqlauthority.com/2008/08/09/sql-server-fix-error-1326-cannot-connect-to-database-server-error-40-could-not-open-a-connection-to-sql-server/
.
I checked the Event Viewer and it told me something else in addition to above,
The reason I get the errors is that the content databases are not at the same version as the application files causing an inability for SharePoint to read the database. Fortunately, you can solve this by running a nice little stsadm command:
so here is what i did,
went to the Command prompt mode, typed the path of the12 Hive, i.e : cd C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN), then gave the following command,
stsadm.exe -o upgrade -forceupgrade -inplace
After Operation successfull completed message, Do an iisreset
Everything started worked beautifully like before. It was another gruilling day of the already hectic month, i immediately made up my mind on writing this article, so as to save my readers from hours of googling and needless stress.
In case, your issue is not resolved, try this: http://support.microsoft.com/kb/934838/en-us
Sunday, November 23, 2008
Submit Infopath form to Sharepoint list
As you know, submitting to a Microsoft Windows SharePoint form library from an InfoPath form is quite simple: just add a “submit” type of data connection to InfoPath and away you go. However, submitting to a SharePoint List is another matter. In this post, we will take a look at the steps necessary to enable this functionality.
Step 1: Create the list
1. Create a new custom list named: MyContacts
2. From the Settings button choose List Settings
3. Click Create Column
4. Add the following columns/data types:
Step 2: Create the CAML template
1. Launch Notepad (or any text editor)
2. Copy and paste the following code to the Notepad document
3. Save this as: Add List Item Template.xml
Step 3: Create the InfoPath Form Template
1. Create a new, blank, browser-compatible form template
2. Add a “Receive” type secondary data connection to the Add List Item Template.xml file created in Step #2. (Make sure the options “Include the data as a resource file in the form template” and “Automatically retrieve data when the form is opened” are enabled.)
3. Add a “Receive” type secondary data connection to the “MyContacts” SharePoint List created in Step #1 and make sure the option “Automatically retrieve data when the form is opened” is enabled.
NOTE: Be sure to include the “Title” field along with the custom fields we created.
Each SharePoint list is created with a unique identifier called a GUID. In order to submit items to a SharePoint list, you must know the unique GUID for that list. These next steps will enable you to identify the GUID for your “MyContacts” list.
Step 4: Identify the list GUID
1. Open a browser and navigate to the MyContacts list
2. From the Settings menu choose List Settings
3. In the browser’s address bar you will see the URL appended with “List=”
4. Copy everything after the equals sign and paste this into a text editor as we will need this value later on.
NOTE: We will need the list GUID to be formatted as “{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}”. If your GUID appears as above with the hyphens and braces “escaped” (i.e. %7B for the braces and %2D for the hyphens) then you will need to replace the escaped characters with the braces and hyphens so when we use this GUID later, it will appear as: {1E76517B-2C36-4473-A420-A737D98589BC}
Step 5: Add controls to the InfoPath Form Template
1. Open the Data Source Task Pane
2. From the Data Source dropdown box choose the “MyContacts” connection
3. Right-click on “MyContacts” and choose Repeating Table – this will add a repeating table bound to that connection to your View
4. From the Data Source dropdown box choose Main
5. Add a text box to the “myFields” node named: ListName and set the Default Value property to the GUID value of your list – we will use this node to specify the list when we perform the Submit operation
To update the SharePoint list we will be using the “UpdateListItems” method of the SharePoint “lists.asmx” web service. This web method requires a couple of parameters (the list name and what gets updated) – now that we have added the “ListName” node which contains the GUID and we have the Add List Item Template XML data connection which describes our data structure we have all the necessary information to add the “UpdateListItems” web method!
Step 6: Add the “lists.asmx” web service
1. Add a new “Submit” type of web service data connection to the “lists.asmx” web service – this is typically located at: http://servername/_vti_bin/lists.asmx
2. Select the “UpdateListItems” operation
3. Double-click the “listname” parameter and assign the “my:ListName” node as the value
4. Double-click the “updates” parameter, select the “Add list Item Parameter” data source, select “Batch” and click OK
5. For the “Include” option select “XML subtree, including selected element”

6. Complete the Data Connection Wizard
Now that we have all the connections that are required, we now need to add the “submit” functionality to the form template.
Step 7: Add Submit functionality
1. Display the Data Source Task Pane
2. From the Data Source dropdown box choose the Add List Item Template data connection
3. Drill down through the data source, right-click on the Field node and choose Repeating Table
We need to change the text box control in the “Name” column to Read-only – if these values were to be changed it would affect the CAML and the submit would fail.
• Double-click on the text box in the Name column of the Repeating Table
• Select the Display tab
• Enable the Read-only property and click OK
• Add a new Button control to the View
• Double-click the button to display the Properties
• Click the Submit Options button
• Enable the option “Allow users to submit this form”
• Enable the option “Perform custom action using Rules” and click the Rules button
• Click the Add button
• Click the Add Action button
• From the Action dropdown box choose “Submit using a data connection”, select the “Web Service Submit” data connection and click OK
• Click the Add Action button
• From the Action dropdown box choose “Query using a data connection”, select the “MyContacts” data connection and click OK (this will automatically refresh the list in InfoPath so you can see the newly added record)
• Click OK until you are back to your form
NOTE: If you want to automatically clear out the submitted values, add another action to this Rule to “Set a field’s value” and the only option you need to specify is the “Field” option – select the “Field” node from the “Add List Item Template” data connection and then simply leave the Value option blank.
Step 8: Test!
1. Click the Preview button to preview the form
2. Fill in values for each of the fields: Title, First Name, Last Name, E-mail and Phone

3. Click the Submit button – the contact information should be submitted successfully and the “MyContacts” list automatically updated!

Courtesy : MSDN
1. Create a new custom list named: MyContacts
2. From the Settings button choose List Settings
3. Click Create Column
4. Add the following columns/data types:
- FirstName, Single line of text
- LastName, Single line of text
- Email, Single line of text
- Phone, Single line of text
Step 2: Create the CAML template
1. Launch Notepad (or any text editor)
2. Copy and paste the following code to the Notepad document
3. Save this as: Add List Item Template.xml
Step 3: Create the InfoPath Form Template
1. Create a new, blank, browser-compatible form template
2. Add a “Receive” type secondary data connection to the Add List Item Template.xml file created in Step #2. (Make sure the options “Include the data as a resource file in the form template” and “Automatically retrieve data when the form is opened” are enabled.)
3. Add a “Receive” type secondary data connection to the “MyContacts” SharePoint List created in Step #1 and make sure the option “Automatically retrieve data when the form is opened” is enabled.
NOTE: Be sure to include the “Title” field along with the custom fields we created.
Each SharePoint list is created with a unique identifier called a GUID. In order to submit items to a SharePoint list, you must know the unique GUID for that list. These next steps will enable you to identify the GUID for your “MyContacts” list.
Step 4: Identify the list GUID
1. Open a browser and navigate to the MyContacts list
2. From the Settings menu choose List Settings
3. In the browser’s address bar you will see the URL appended with “List=”
NOTE: We will need the list GUID to be formatted as “{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}”. If your GUID appears as above with the hyphens and braces “escaped” (i.e. %7B for the braces and %2D for the hyphens) then you will need to replace the escaped characters with the braces and hyphens so when we use this GUID later, it will appear as: {1E76517B-2C36-4473-A420-A737D98589BC}
Step 5: Add controls to the InfoPath Form Template
1. Open the Data Source Task Pane
2. From the Data Source dropdown box choose the “MyContacts” connection
3. Right-click on “MyContacts” and choose Repeating Table – this will add a repeating table bound to that connection to your View
4. From the Data Source dropdown box choose Main
5. Add a text box to the “myFields” node named: ListName and set the Default Value property to the GUID value of your list – we will use this node to specify the list when we perform the Submit operation
Step 6: Add the “lists.asmx” web service
1. Add a new “Submit” type of web service data connection to the “lists.asmx” web service – this is typically located at: http://servername/_vti_bin/lists.asmx
2. Select the “UpdateListItems” operation
3. Double-click the “listname” parameter and assign the “my:ListName” node as the value
4. Double-click the “updates” parameter, select the “Add list Item Parameter” data source, select “Batch” and click OK
5. For the “Include” option select “XML subtree, including selected element”
6. Complete the Data Connection Wizard
Now that we have all the connections that are required, we now need to add the “submit” functionality to the form template.
Step 7: Add Submit functionality
1. Display the Data Source Task Pane
2. From the Data Source dropdown box choose the Add List Item Template data connection
3. Drill down through the data source, right-click on the Field node and choose Repeating Table
• Double-click on the text box in the Name column of the Repeating Table
• Select the Display tab
• Enable the Read-only property and click OK
• Add a new Button control to the View
• Double-click the button to display the Properties
• Click the Submit Options button
• Enable the option “Allow users to submit this form”
• Enable the option “Perform custom action using Rules” and click the Rules button
• Click the Add button
• Click the Add Action button
• From the Action dropdown box choose “Submit using a data connection”, select the “Web Service Submit” data connection and click OK
• Click the Add Action button
• From the Action dropdown box choose “Query using a data connection”, select the “MyContacts” data connection and click OK (this will automatically refresh the list in InfoPath so you can see the newly added record)
• Click OK until you are back to your form
NOTE: If you want to automatically clear out the submitted values, add another action to this Rule to “Set a field’s value” and the only option you need to specify is the “Field” option – select the “Field” node from the “Add List Item Template” data connection and then simply leave the Value option blank.
Step 8: Test!
1. Click the Preview button to preview the form
2. Fill in values for each of the fields: Title, First Name, Last Name, E-mail and Phone
3. Click the Submit button – the contact information should be submitted successfully and the “MyContacts” list automatically updated!
Courtesy : MSDN
Subscribe to:
Posts (Atom)
