Using SharePoint Search feature in ASP.Net Application


Using SharePoint Search feature in ASP.Net Application


Integrating ASP.Net application in to MOSS 2007 to utilize SharePoint Enterprise Search Feature can be done by using Business Data Search.

We can enable full text search for our .Net application in following steps:


  • Create Business Data Catalog metadata model for our .Net application, which basically defines contract between MOSS and the .Net business application data. The BDC contract includes data connection information, business entities, and methods to access business data. Additionally you may specify security information.

  • Import BDC metadata model (XML file from step above) using SharePoint SSP Admin
    site and create a business data catalog (BDC). We can also define full
    & incremental crawl schedule for your business data.

  • Define search scope to include our BDC crawl data. This makes crawled business data to
    searchable.

  • Once SharePoint crawl business data, SharePoint automatically create profile web pages. Profile pages are used by MOSS to display Business data details when a result row in search result page is clicked.


MSDN suggested Procedure to configure Business Data

  1. For line-of-business applications, register the application in the Business Data Catalog and set the number of connections.

  2. Create a content source for the business application data.

  3. Crawl the content source for the application data to add its properties as new crawled properties in the portal site schema.

  4. Select the relevant properties in the Configure Search section of the Business Data Catalog and map them to managed properties for search.

  5. Create ACLs for business data types in the Business Data Catalog.

  6. Crawl the content source for the business data source again to update managed properties and ACLs.

  7. Create search scopes for business data.

  8. Configure keywords for business data.

Business data search results can be displayed in four distinct ways:


  • When a search scope that includes business data is used to search, the search
    results include business data results. A business data search scope is not
    provided by default, but administrators can create search scopes that include
    business data.

  • Users can refine initial search results by selecting the option to search business
    data sources.

  • Users can select a business data tab provided in the Search Center
    site, and the search will include all business data for the tab. A tab for all
    business data is not included by default, but administrators can add tabs for
    searching all business data or for searching data from specific business
    applications.

  • If the search term in a standard search query matches a keyword phrase selected by an administrator, the business data result appears in recommended results.

We can search the .Net business data in following ways


  • SharePoint portal
  • Expose it as SharePoint list
  • Create Business Data Web Parts and
  • Use SharePoint Search Web service and create your own custom search application



Note: The integration of business data is available only in the enterprise version of Office SharePoint Server 2007.Deployments of the standard version of Office SharePoint Server 2007 cannot register business data applications or search for business data by using enterprise search.






MOSS Best Practices & Coding Guidelines

MOSS Best Practices & Coding Guidelines



1. Common development Issues in SharePoint objects:

A Bad SharePoint code can be one of the key factors for degrading the performance. We should be careful on the following areas when we write the custom code…

· Disposing of SharePoint objects

· Caching data and objects

· Writing code that is scalable

1.1. Disposing ­­­SharePoint objects

We all know that SPSite class and SPWeb class objects are created as managed objects. However, these objects use unmanaged code and memory to perform the majority of their work. Unfortunately the managed part of the object is small; the unmanaged part of the object is much larger. We should not rely on the garbage collector to release objects from memory automatically. 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.

1.1.1. Problems in not disposing SharePoint object

In the SharePoint object model, the Microsoft.SharePoint.SPSite and Microsoft.SharePoint.SPWeb objects are created in managed code as a small wrapper (approximately 2 KB in size). This wrapper then creates unmanaged objects, which can average approximately 1–2 MB in size. If your code resembles the following code example, and if you assume that the SPWeb.Webs collection has 10 subsites, a total of 10 items are created, each with an average of 2 MB of memory (for a total of 20 MB).

Sample code

public void GetNavigationInfo()
{

SPWeb oSPWeb = SPContext.Web;
// .. Get information oSPWeb for navigation ..
foreach(SPWeb oSubWeb in oSPWeb.GetSubWebsForCurrentUser())
{
// .. Add subweb information for navigation ..
}
}

Table 1. Best and worst case memory usage as number of users increases

Users

Best Case

Worst Case

10

100 MB

200 MB

50

500 MB

1000 MB

100

1000 MB

2000 MB

250

2500 MB

5000 MB

The following unusual behaviors can happen because of non-disposing objects

· 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

1.1.2. Coding Techniques to follow:

Power of Using Clause:

Using clause automatically disposes the SharePoint objects. It implements the IDisposable interface.

String str;
using(SPSite oSPsite = new SPSite("http://server"))
{

using(SPWeb oSPWeb = oSPSite.OpenWeb())

{
str = oSPWeb.Title;
str = oSPWeb.Url;
}

}

Make sure that the following objects are properly disposed either by using Using Clause or by uinsg Dispose method:

a. SPSite.OpenWeb - creates new items and should be disposed of.

b. SPSite.RootWeb and SPWeb.ParentWeb - creates new objects and assign them to a local member variable.

c. SPSite() constructors

a. SPSite (Guid) Initializes a new instance of the SPSite class based on the specified GUID for a site collection.

b. SPSite (String) Initializes a new instance of the SPSite class based on the specified absolute URL.

c. SPSite (Guid, SPUrlZone) Initializes a new instance of the SPSite class based on the specified site collection GUID and URL zone.

d. SPSite (Guid, SPUserToken) Initializes a new instance of the SPSite class based on the specified site collection GUID and user token.

e. SPSite (String, SPUserToken) Initializes a new instance of the SPSite class based on the specified absolute URL and user token.

f. SPSite (Guid, SPUrlZone, SPUserToken) Initializes a new instance of the SPSite class based on the specified site collection GUID, URL zone, and user token.

d. SPSiteCollection Class

e. SPSiteCollection.Add method - It creates and returns a new SPSite object

f. SPSiteCollection [ ] Index Operator - It returns a new SPSite object for each access

Bad Practice:

a. SPGlobalAdmin oSPGlobalAdmin = new SPGlobalAdmin();
SPSiteCollection aSites = oSPGlobalAdmin.VirtualServers[0].Sites;
SPSite oSPSite = aSites.Add( ... );
... Process the site info ...
oSPSite.Dispose();
oSPGlobalAdmin.Dispose();

b. SPGlobalAdmin oSPGlobalAdmin = new SPGlobalAdmin();
SPSiteCollection aSites = oSPGlobalAdmin.VirtualServers[0].Sites;
foreach(SPSite oSPSite in aSites)
{
BuildTableRow(oDisplayTable, "Site", oSPSite.Url);
}
oSPGlobalAdmin.Dispose();

Good Practice:

a. int i;
SPSite oSPSite;
SPGlobalAdmin oSPGlobalAdmin = new SPGlobalAdmin();
SPSiteCollection aSites = oSPGlobalAdmin.VirtualServers[0].Sites;
for(i = 0;i < aSites.Count;i++)
{
oSPSite = aSites[i];
BuildTableRow(oDisplayTable, "Site", oSPSite.Url);
oSPSite.Dispose();
}
oSPGlobalAdmin.Dispose();

b. int i;
SPGlobalAdmin oSPGlobalAdmin = new SPGlobalAdmin();
SPSiteCollection aSites = oSPGlobalAdmin.VirtualServers[0].Sites;
for(i = 0;i < aSites.Count;i ++)
{
using(SPSite oSPSite = aSites[i])
{
BuildTableRow(oDisplayTable, "Site", oSPSite.Url);
}
}
oSPGlobalAdmin.Dispose();

g. SPSite.AllWebs Property (SPWebCollection) - SPSites.AllWebs.Add Method

h. SPSite.OpenWeb

i. SPSite. SelfServiceCreateSite Methods - Creates a SPWeb object and return it to the caller

j. SPSite.LockIssue, SPSite.Owner, and SPSite.SecondaryContact Properties - All these properties reference data from the top-level Web site and use the SPSite.RootWeb property

k. SPSite.RootWeb property – This property determines whether a member variable is assigned with a non-null value. If the member variable is null, a new SPWeb object is created by calling SPSite.OpenWeb method.

l. SPWeb Objects

m. SPWeb.ParentWeb Property

n. Area.Web property - It returns a new SPWeb object each time it is accessed

o. WebPartPage.RootWeb Property - The WebPartPage.RootWeb property is similar to the SPSite.RootWeb property in that the first time the property

1.1.3. Dispose Vs Close:

Though Dispose and close dose the same thing, Microsoft recommends to use Displose for the following reason…

· SPWeb and SPSite objects implement the IDisposable interface, and the standard .NET Framework process calls the Dispose method to free from memory any resources associated with the object.

· Future releases of your code are ensured to be called properly.

1.2. Caching Data and Objects

Many of us are using Microsoft .NET Framework caching objects (for example, System.Web.Caching.Cache) to help make better use of memory and increase overall system performance. But, many objects are not "thread safe" and caching those objects can lead to application crashes and unexpected or unrelated user errors.

1.2.1. Caching SharePoint Objects That Are Not Thread Safe

We are trying to increase performance and memory usage by caching SPListItemCollection objects that are returned from queries. In general, this is a good practice but the SPListItemCollection object contains an embedded SPWeb object that is not thread safe and should not be cached. For example, assume the SPListItemCollection object is cached in thread A. Then, as other threads try to read it, the application can fail or behave strangely because the object is not thread safe.

1.2.2. Not Using Thread Synchronization

Sometimes we are not aware that we are running in a multi-threaded environment (by default, Internet Information Services is multi-threaded) or how to manage that environment. The following code example shows the caching Microsoft.SharePoint.SPListItemCollection objects.

Sample code

public void CacheData()
{
SPListItemCollection oListItems;
oListItems = (SPListItemCollection)Cache["ListItemCacheName"];
if(oListItems == null)
{
oListItems = DoQueryToReturnItems();
Cache.Add("ListItemCacheName", oListItems, ..);
}
}

In the previous code example, the problem is that if the query to get the data takes 10 seconds, our could have many users hitting that page at the same time, all running the same query and trying to update the same cache object at the same time. This can cause performance issues because the same query might be running 10, 50, or 100 times and can cause crashes because multiple threads are trying to update the same object at the same time, especially on multi-process, hyper-threaded computers. To fix this, we must change the code as follows.

Sample Code

public void CacheData()
{
SPListItemCollection oListItems;
lock(this)
{
oListItems = (SPListItemCollection)Cache["ListItemCacheName"];
if(oListItems == null)
{
oListItems = DoQueryToReturnItems();
Cache.Add("ListItemCacheName", oListItems, ..);
}
}
}

It is possible to increase performance slightly by placing the lock inside the if(oListItems == null) code block. When we do this, we do not need to suspend all threads while checking to see if the data is already cached. Depending on how long it takes the query to return the data, there is still the possibility that more than one user might be running the query at the same time.

1.2.3. Caching an object which is thread safe

Sample code: Using DateTable object which is thread safe

public void CacheData()
{
DataTable oDataTable;
SPListItemCollection oListItems;
lock(this)
{
oDataTable = (DataTable)Cache["ListItemCacheName"];
if(oDataTable == null)
{
oListItems = DoQueryToReturnItems();
oDataTable = oListItems.GetDataTable();
Cache.Add("ListItemCacheName", oDataTable, ..);
}
}
}

1.3. Writing Code That Is Scalable

Writing scalable code is very important when we handle multiple users at the same time.

1.3.1. A few things that we need to take into consideration when asking how to make code more scalable

· Is the data static (seldom changes), somewhat static (changes occasionally), or dynamic (constantly changing)?

· Is the data the same for all users, or does it change? For example, does it change depending on the user who is logged on, the part of the site being accessed, or the time of year (seasonal information)?

· Is the data easily accessible or does it require a long time to return the data? For example, is it returning from a long-running SQL query or from remote databases that can have some network latency in the data transfers?

· Is the data public or does it require a higher level of security?

· What is the size of the data?

· Is the SharePoint site on a single server or on a server farm?

A good example of this is creating custom navigation information for all sites and subsites on each page or as part of a master page. For example, if we have a SharePoint site on a corporate intranet and each department has its own site with many subsites, our code might resemble the following.

public void AddAllWebs(SPWeb oSPWeb)
{
foreach(SPWeb oSubWeb in oSPWeb.Webs)
{
//.. Code to add items ..
AddAllWebs(oSubWeb);
oSubWeb.Dispose();
}
}

While the previous code disposes of objects properly, it still causes problems because the code is going through the same lists over and over. For example, if we have 10 site collections and an average of 20 sites or subsites per site collection, we would iterate through the same code 200 times. For a small number of users this might not cause bad performance. But, as we add more users to the system, the problem gets worse. Table 2 shows this.

Table 2. Iterations increase as the number of users increase

Users

Iterations

10

2000

50

10000

100

200000

250

500000

The above code executes for each user that hits the system, but the data remains the same for everyone. The impact of this can vary depending on what the code is doing. The above code creates a lot of performance overhead.

There are several ways we can make our code more scalable and handle multiple users.They are...

· Caching Raw Data

· Building Data Before Displaying It

· Caching for a Single Server or Server Farm

1.3.2. Caching Raw Data

we can cache our data by using the System.Web.Caching.Cache object. This object requires that we query the data one time and store it in the cache for access by other users.

If our data is static, we can set up the cache to load the data once and not expire until the application is restarted or to load once a day to ensure data freshness. We can create the cache item when the application starts, when the first user session starts, or when the first user tries to access that data.

If our data is somewhat static, we can set up the cached items to expire within a certain number of seconds, minutes, or hours after it is created. This enables us to refresh your data within a timeframe that is acceptable to our users. Even if the data is cached for only 30 seconds, under heavy loads we will still see an increase of performance because we are running the code only once every 30 seconds instead of multiple times a second for every user hitting the system.

Be sure to take into consideration the issues outlined previously in Caching Data and Objects.

1.3.3. Building Data before Displaying It

We should think how our cached data will be used. If this data is used to make run-time decisions, putting it into a DataSet or DataTable object might be the best way to store it. We can then query those objects for the data to make run-time decisions. If the data is being used to display a list, table, or formatted page to the user, consider building a display object and storing that object in the cache. At run time, we need only to retrieve the object from the cache and call its render function to display its contents. We could also store the rendered output, but this can lead to security issues and the cached item could be quite large, causing a lot of page swapping or memory fragmentation.

1.3.4. Caching for a Single Server or Server Farm

Depending on how our SharePoint site is set up, we might have to address some caching issues differently. If our data must be the same on all servers at all times, then we must ensure that the same data is cached on each server. One way to ensure this is to create the cached data and store it on a common server or in an SQL database. Again, we must consider how long it takes to access the data and any security issues of the data being stored on a common server.

2. Things to check before check in the code

To ensure that our SharePoint system performs at its best, we need to check the following points

  • Does our code properly dispose of SharePoint objects?
  • Does our code cache objects properly?
  • Does our code cache the correct types of objects?
  • Does our code use thread synchronization when necessary?
  • Does our code work as efficiently for 1000 users as it does for 10 users?

Creating Sites/Lists/List Items under Current User Context in SharePoint By Using SPUserToken



Creating Sites/Lists/List Items under Current User Context in SharePoint By Using SPUserToken



We might have come across the situation where we need to perform a certain action on a particular user context in MOSS 2007.

Usually we do this by performing the action under RunWithElevatedPrivileges method and updating the listitem using SPListItem.SystemUpdate() method (see here). but this approach has its own flaws like (RunWithElevatedPrivileges will run under system account, we cannot use SystemUpdate for SPSite,SPWeb,SPList, since it runs under system we will "CreatedBy" by as SystemAccount).

by using SPUserToken we can achive this without RunWithElevatedPrivileges method. All we need to do is create SPSite by passing SPUserToken of a particular user.

In below example i'm creating SPUserToken object by calling GetUserToken method.

Example:

string siteUrl = "Ur Site Url Goes Here";
string username = "YourUsername";
SPUserToken spusertoken = GetUserToken(siteUrl, username);
SPSite spsite = new SPSite(siteUrl, spusertoken);
SPWeb spweb = spsite.OpenWeb().Webs["WebName"];
SPList list = spweb.Lists["MyList"];
SPListItem item = list.Items.Add();
item["Title"] = "TestTitle";
item.Update();
spsite.OpenWeb().Dispose();
spweb.Dispose();
spsite.Dispose();

private static SPUserToken GetUserToken(string siteUrl, string userName)
{
SPUserToken userToken = null;
using (SPSite site = new SPSite(siteUrl))
{
foreach (SPUser user in site.RootWeb.AllUsers)
{
string siteUserName = user.LoginName;
if (user.LoginName.IndexOf(':') != -1)
{
string[] DomainAndUser = user.LoginName.Split(new char[] { ':' });
siteUserName = DomainAndUser[1];
}
else if (user.LoginName.IndexOf('\\') != -1)
{
string[] DomainAndUser = user.LoginName.Split(new char[] { '\\' });
siteUserName = DomainAndUser[1];
}
if (siteUserName == userName)
{
userToken = user.UserToken;
Console.WriteLine("User token found");
break;
}
}
}
return userToken;
}

Google Chrome with SharePoint - First decent step for Google Chrome




Today I installed the just released Google Chrome browser and tested it with my SharePoint application.


So far it looks ok, it renders links, menus, sites and application pages correctly. but sucks while dragging and dropping the webpart in edit mode.





There is one more issue With document library, while editing the document it gave me "'Edit Document' requires a Windows SharePoint Services-compatible application and Microsot Internet Explorer 6.0 or greater." error message.




For normal browsing it works great! Its a decent release for google chrome, expecting that all above issues will be fixed in next version.

Download the Google Chrome from here



How to track the changes of user contacts(colleagues) by using SharePoint API




We might have seen colleague tracker web part which keep tracks the changes made in our contacts/colleagues details like profile/lists/sites. The same tracking mechanism can be implemented by using MOSS API in any custom web part/ web control/ feature/web service...

UserProfile.GetColleagueChanges is the method which returns all changes happened with the contacts, this method also accepts a Query (UserProfileChangeQuery) where we can specify different parameters to filter the changes


I have given below the example to use GetColleagueChanges method


UserProfileManager userProfileManager = new UserProfileManager(ServerContext.Default);
UserProfile userProfile = userProfileManager.GetUserProfile("MyLoginName");

//Change the start date to get the changes from certain date
DateTime startDate = DateTime.Today;

UserProfileChangeQuery userProfileChangeQuery = new UserProfileChangeQuery(true, true);
UserProfileChangeToken userProfileChangeToken = new UserProfileChangeToken(startDate);
userProfileChangeQuery.ChangeTokenStart = userProfileChangeToken;
userProfileChangeQuery.UserProfile = true;
userProfileChangeQuery.PersonalizationSite = true;
userProfileChangeQuery.Update = true;
userProfileChangeQuery.Add = true;
userProfileChangeQuery.Delete = true;
userProfileChangeQuery.SingleValueProperty = true;
userProfileChangeQuery.MultiValueProperty = true;
userProfileChangeQuery.Colleague = true;
userProfileChangeQuery.SiteMembership = true;
userProfileChangeQuery.Anniversary = true;

UserProfileChangeDictionary userProfileChangeDictionary = userProfile.GetColleagueChanges(userProfileChangeQuery);

Dictionary.Enumerator userProfileChangeCollection = userProfileChangeDictionary.GetEnumerator();
while (userProfileChangeCollection.MoveNext())
{
UserProfileChangeCollection userProfileChanges = userProfileChangeCollection.Current.Value;
foreach (UserProfileChange userProfileChange in userProfileChanges)
{
if (userProfileChange is UserProfileSingleValueChange)
{
UserProfileSingleValueChange propertyChange = (UserProfileSingleValueChange)userProfileChange;
//propertyChange will have the new and old value of profile fileds
}
else if (userProfileChange is UserProfileMultiValueChange)
{
UserProfileMultiValueChange propertyChange = (UserProfileMultiValueChange)userProfileChange;
//propertyChange will have the new and old value of profile fileds
}
else if (userProfileChange is UserProfileWebLogChange)
{
UserProfileWebLogChange listChange = (UserProfileWebLogChange)userProfileChange;
//listChange will have the newly added/modifed list item url
}
}
}


Above code will return all the changes happened in profiles/lists/sites for all contacts/colleagues....





Power of using Clause in SharePoint



Power of using Clause in SharePoint


The Using Clause will help to avoid memory leaks in SharePoint by automatically Disposing the MOSS objects.

For example when we create SPSite and SPWeb objects, if we don't dispose it explicitly it might create memory leaks,

the given below code is not a good practice as it might trigger memory leakage...

SPSite spSite = new SPSite("http://mysharepointserver");
SPWeb spWeb = spSite.OpenWeb();
SPUser spUser = spSite.SystemAccount;


the same code can be written with using clause like below to avoid memory leakage...

using (SPSite spSite = new SPSite("http://mysharepointserver"))
{
SPWeb spWeb = spSite.OpenWeb();
SPUser spUser = spSite.SystemAccount;
}


more details on avoiding memory leak on different situations can be found here




Visual Studio 2008 Extensions for Windows SharePoint Services 3.0


Visual Studio 2008 Extensions for Windows SharePoint Services 3.0 (Version 1.2)

The much awaited VSeWSS Version 1.2 has been released in this week. You can get it here

Summary

  • It works only with VS2008 (for VS2005 we must use version 1.1 click here)

  • It supports Windows SharePoint Services and Office SharePoint Server.

  • IT works only against local SharePoint installations.


Changing the SharePoint List listitem's permission in event handler



Changing the SharePoint List listitem's permission in event handler


In MOSS 2007 ListItem permission's could be changed by overriding Add\Update event in eventhandler.


Write a eventhandler class (which inherits from SPItemEventReceiver class) as given below...


public override void ItemUpdated(SPItemEventProperties properties)
{
string
sGroupName = "Group Name";
spWeb = properties.OpenWeb();
spWeb.AllowUnsafeUpdates = true;
SPGroupCollection spGroupCollection = spWeb.SiteGroups;
SPRoleDefinition spRoleDefinition = spWeb.RoleDefinitions.GetByType(SPRoleType.Reader);
properties.ListItem.BreakRoleInheritance(true);


foreach (SPRoleAssignment spRoleAssignment in properties.ListItem.RoleAssignments)
{
//Add your conditions to remove/not remove the existing permissions
spRoleAssignment.RoleDefinitionBindings.RemoveAll();
spRoleAssignment.Update();
}


if (spGroupCollection != null)
{
SPRoleAssignment spRoleAssignment = new SPRoleAssignment((SPPrincipal)spGroupCollection[sGroupName]);
spRoleAssignment.RoleDefinitionBindings.Add(spRoleDefinition);
properties.ListItem.RoleAssignments.Add(spRoleAssignment);
}


this.DisableEventFiring();
UpdateUserGroups(spWeb, properties);
this.EnableEventFiring();
spWeb.AllowUnsafeUpdates = false;
spWeb.Dispose();
}


the above code dose the following...

  • overrides ItemUpdated event (you can do the same for any Item level event)
  • removes all existing permission for the current updated list item
  • adds the Reader permission only for group sGroupName (You can also give contributor permission by changing SPRoleType.Reader to Contributor)

Deploy and attach this event handler to the list where you want to change the ListItem permission whenever the user updates the list item...



Hiding the Context menu item of a Document Library in a SharePoint



Hiding the Context menu item of a Document Library in a SharePoint

Sometimes we found that the some context menu (like "Alert Me", "WorkFlow", etc) in Document Library's is not required for the users, One of my client asked me to take iout the "Alert Me" menu...After some R&D :), i addressed the client requirement

There is a function called "CAMOpt" in Core.JS, this function is used to add new item in ListItem's context menu...the above requirement can be done by writing a new "CAMopt" JS function to override the Core.JS's "CAMOpt" JavaScript method

i wrote a new function (called CAMOpt) to override CMOpt


JS funciton in
Core.JS...

function CAMOpt(p,wzText,wzAct,wzISrc,wzIAlt,wzISeq,wzDesc)
{
var mo=CMOpt(wzText,wzAct,wzISrc,wzIAlt,wzISeq,wzDesc);
if(!mo)return null;
if(wzText != "Alert Me") AChld(p,mo);
return mo;
}






New overriden JS funciton in document library's allitems page...


function CAMOpt(p,wzText,wzAct,wzISrc,wzIAlt,wzISeq,wzDesc)
{
var mo=CMOpt(wzText,wzAct,wzISrc,wzIAlt,wzISeq,wzDesc);
if(!mo)return null;
if(wzText != "Alert Me") AChld(p,mo);
return mo;
}






Context menu item of ListItem could be Edited/Deleted/Added by using above approach...


Defining Custom methods for Pre-defined (inbuilt) Java Script methods




HOW to Define Custom methods for Pre-defined (inbuilt) Java Script methods


Some times i face the situation where i would need to override the existing inbuilt Java Script methods...Defining custom method is pretty easy, i have given below an example to override the existing Alert method...

//Overriding Javascript Alert method
var alertClone=window.alert;
if(document.getElementById)
{
window.alert = function(sMessage) { customAlert(sMessage);}
}

function customAlert(sMessage)
{
alertClone(sMessage);
}



just copy paste the code in your JavaScript and add your code inside CustomAlert() method...



Creating MOSS 2007 Virtual Machine



Creating MOSS 2007 Virtual Machine

Its a recommended to create Virtual machine (VPC image) to play around with MOSS 2007 (especially for beginners).

Couple of my friends were asking about creating VM machine with MOSS environment. We used to create it from base (Rgith from installing Win 2003 following with Office 2007, VS 2005, SQL 2005, .Net 3.0, WFF and MOSS 2007), and it would take a day or two to build a VM for Share Point 2007 (Here is link to create SharePoint 2007 VM on our own).

But now we don't need put that much effort to build a SharePoint VPC as Microsoft provides already built VPC image for MOSS 2007, Microsoft has uploaded it in Microsoft's Download center site (it expires after 30days, but u can always renew it with a different id)


Do the following steps to setup VPC for MOSS 2007...

Step 1: Please Insatll IIS in your host machine(laptop/desktop PC), Go to for more details about installing IIS on ur machine

Step 2: Downlad Microsoft Virtual Server here and install it, Please go to here for more information about Microsoft Virtual PC

Step 3: Click here and Download all six files.

Step 4: Run WIN03_MOSS_V1.part01.exe

Step 5: Above step Will join all five rar files and will create one VHD (Virtul Hard Disk), one VMC(Confiuration file) and a ReadMe file (documentation file which tells crelarly about opening the Virtual Hard Disk by using Microsoft Virtual Server)

Step 6: Open VHD by using Microsoft Virtual Server( Read me ReadMe file for help)

Play around with MOSS 2007 virtual machine




.STP Language Converter


.STP Language Converter

I found a STP Language Converter utility in kwizcom, which enables you to convert a Site Template (.stp) file that was created in one language, to a site template in another language.

Please click here to download the STP Language converter tool



SharePoint Tips Utility Pack




SharePoint Tips Utility Pack



Recently i came across a tool from CodePlex , Its very useful tool for Site/List administrators who wants Modify/Delete their Site, SiteContents, List, Listcontent, Event Handlers, etc

Here is the link for the tool...





How to see list templates (stp) and site templates (stp) gallery




How to see list templates (stp) and site templates (stp) gallery :


List Templates:
Its simple, go to _catalogs/lt/Forms/AllItems.aspx from the top level site to see all ListTemplates (stp) associated with that the site, will see a gallery like below





Site Templates:
For Site template gallery go to _catalogs/wt/Forms/AllItems.aspx from the top level site to see all SiteTemplates (stp) associated with that the site, will see a gallery like below











SPUser Group Management



SPUser Group Management


How to Create\Update\Retrieve\Delete a Personal UserGroup for a User in SharePoint by using APIs



Personal User Groups can be Created, Updated, Retrieved and Deleted by using SharePoint APIs as given below...


//Create Group
SPUser spUser = mySite.Owner;
SPMember spMemebr = mySite.RootWeb.Users["My User Name"];
spUser.Groups.Add("GroupName", spMemebr, spUser, "This is Group Description");
spUser.Update();


//Update Group
SPUser spUser = mySite.Owner;
SPGroup spGroup = spUser.Groups["GroupName"];
spGroup.Name = "newGroupName";
spGroup.Update();


//Retrieve Group
SPUser spUser = mySite.Owner;
SPGroupCollection spGroupCollection = spUser.Groups;


foreach (SPGroup spGroup in groupCollection)
{
//Store all groups in internal collection
}

//Delete Group
SPUser spUser = mySite.Owner;
spUser.Groups.Remove("newGroupName");
spUser.Update();



Save Site As Template

Save Site As Template


How to Save Site As Template (stp file)

Go to "/_layouts/savetmpl.aspx" in your current site, Now you will see the option to save your current site as template. (screenshot given below)
Enter the stp file name and check the checkbox "Include Content" if you want to include the all content (lists, libraries,etc) from the site current site.



Note: If your Publishing Feature is not turned on you will see the "save site as template" option under SiteSettings -> LookAndFeel section, the above scenario will apply only when the Publishing Feature is turned off.