Friday, November 14, 2008

SPDisposeCheck Tool will be available soon

Memory management in SharePoint coding is always been an ongoing issue and topic of dicsussin among developers. When to dispose SPWeb and SPSite objects when not to is been a biggest confusion. There have been many best practices and white papers from experts which talks about this but there are some confusions still pending and it becomes diffcult to judge and find when you have 1000s of lines of code and classes written. Microsoft wants to help us developers for writing quality code which takes care of memory dispose and makes best use of available memory. There is a tool coming up soon as mentioned in MSDN SharePoint blog. Read more here and wait for the Memory Doctor to be released ;-)

http://blogs.msdn.com/sharepoint/archive/2008/11/12/announcing-spdisposecheck-tool-for-sharepoint-developers.aspx

Thursday, November 6, 2008

MCTS 70-542

Ok its been quite busy in last few weeks. Lot of developments and excitements happening. News! I have successfully passed MOSS Application development exam (70-542). Some tips to clear this exam:

A very good undeerstanding of MOSS as a platform.
Good hands on creating and developing BDC's.
Good knowledge on Excel services and UDF's and related object model
Understand Search configurations, settings and related object model.
Understanding of IRM policies.
Portal template.
Some understanding on Audience and User profile.

Check the preparation guide:
http://www.microsoft.com/learning/en/us/exams/70-542.mspx

Also do the e-learning course collection 6071 if you can (Its worth the money!):
https://www.microsoftelearning.com/eLearning/offerDetail.aspx?offerPriceId=138720

And if you have any questions then feel free to contact me.

Friday, October 17, 2008

Installing 64 bit MOSS with a 32 bit SQL Server (Using SQL Alias)

I have come across a issue which took me a while to figure out the reason.

Problem: I was installing 64 Bit Version of MOSS and configuring the databases on a 32 Bit SQL server. Now on the MOSS server I had 32 bit SQL client tools to setup the SQL server alias. So my connection string when configuring MOSS was "SharePointSQLServer" for the SQL server 10.x.x.x on instance ABC01 port 1435 (10.x.x.x\ABC01, 1435). Now I was setting up the alias on MOSS server using SQL client tools. For some reason confuguration wizard was not detecting the correct SQL alias and was throwing me error of cannot connect to DB server.

Solution and Attempts:
  • I tried different sets of aliases but no help. For example tried using machine name instead of IP, tried using FQDN of machine name, tried without instance name. No help!
  • Then I thought it might be 32 bit client tools. So I tried removing 32 bit version and installed 64 bit version of SQL client tools. Still No help!
  • Worked Solution: Then I went through the registry entries at:
(32 Bit Location)
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MSSQLServer\Client\ConnectTo

The SQL client tools add the regisrty entry to this location for 32 bit applications running on 64 bit operating System. But MOSS 64 Bit configuration wizard was not reading from this location and instead trying to use the Alias name directly from some other location.

So I went and checked in registry entries at this location:
(64 Bit Location)HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client

And there was no ConnectTo key. So even after installing 64 Bit version of SQL client tools the conenction string was not getting set at above location and was going into Wow6432Node key which is used for 32 bit applications. So I created a ConnectTo key by exporting from 32 Bit Location (Wow6432Node) and importing into 64 Bit Location so that my registry key on MOSS server looks like this:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo

And checked that the value of connection string is: "DBMSSOCN,SharePointSQLServer,PortNumber"

And guess what? Yes it worked!

So on 64 Bit Windows 2003 machines if you get any issues related to entries in regisrty keys then you know where and what to look for :-)

Let me know if you have any questions on this.

Cheers,
Kunal

Wednesday, October 8, 2008

Error Event ID 5555, Event ID 7888 after changing Web App Association with new SSP

I had come across a strange issue which exposes some of the inabilities of MOSS. I had to recreate SSP in a SharePoint Farm. I then went and changed the association of web applications to point to new SSP so that I can get rid of old faulty SSP. (It was faluty because the search was stuck on "Crawling Full (Computing Ranking)" status and when tried to remove the SSP it was then stuck on "Unprovisioning" status). So to remove the old SSP:
- I created a new SSP.
-Associated web applications from old SSP to new SSP through Central Administration.
-Change the default SSP to new one.
-Deleted the old SSP including all associated databases.
-Deleted old SSP web application.

After this next day I saw in event logs there were errors thrown related synchronization of MySite and Portal web application with content databases. The errors were as below:

Event Type: ErrorEvent Source: Office SharePoint ServerEvent Category: User Profiles Event ID: 5555Date: 8/10/2008Time: 1:01:00 PMUser: N/AComputer: AUYXUAP310WBC32Description:Failure trying to synch web application ab1d413c-4e4b-40af-b9f2-61fedadb385d, ContentDB 4876d341-5349-4396-b0a9-3cb6f5110b1c Exception message was Cannot open database "WSS_SharedServices2_DB" requested by the login. The login failed.Login failed for user 'ESDEVAU\SRV-SHRPT07'.
For more information, see Help and Support Center at
http://go.microsoft.com/fwlink/events.asp.

Event Type: ErrorEvent Source: Office SharePoint ServerEvent Category: Office Server General Event ID: 7888Date: 8/10/2008Time: 1:01:00 PMUser: N/AComputer: AUYXUAP310WBC32Description:A runtime exception was detected. Details follow. Message: Cannot open database "WSS_SharedServices2_DB" requested by the login. The login failed.Login failed for user 'ESDEVAU\SRV-SHRPT07'.
Techinal Details:System.Data.SqlClient.SqlException: Cannot open database "WSS_SharedServices2_DB" requested by the login. The login failed.Login failed for user 'ESDEVAU\SRV-SHRPT07'. at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject) at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection) at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory) at System.Data.SqlClient.SqlConnection.Open() at Microsoft.Office.Server.Data.SqlSession.OpenConnection() at Microsoft.Office.Server.Data.SqlSession.ExecuteReader(SqlCommand command, CommandBehavior behavior) at Microsoft.Office.Server.Administration.SharedObjectStore.GetObject[T]() at Microsoft.Office.Server.Administration.SharedResourceProvider.Microsoft.Office.Server.Administration.ISharedObjectStore.GetObject[T]() at Microsoft.Office.Server.Administration.SharedApplicationCollection`1.GetValue(SharedResourceProvider sharedResourceProvider) at Microsoft.Office.Server.Administration.SharedApplicationCollection`1.get_Item(SharedResourceProvider sharedResourceProvider) at Microsoft.Office.Server.ServerContext.GetApplication[S,T](String name) at Microsoft.Office.Server.Search.Administration.SearchContext..ctor(ServerContext serverContext, Boolean cached) at Microsoft.Office.Server.Search.Administration.SearchContext.GetContext(SharedResourceProvider sharedResourceProvider) at Microsoft.Office.Server.UserProfiles.SRPSite.SynchronizeManagedPropertyMappings() at Microsoft.Office.Server.UserProfiles.SRPSite._Init(ServerContext serverContext) at Microsoft.Office.Server.UserProfiles.SRPSite..ctor(ServerContext serverContext) at Microsoft.Office.Server.UserProfiles.UserProfileConfigManager..ctor(ServerContext serverContext) at Microsoft.Office.Server.UserProfiles.ContentDBSynchronizer.SynchContentDB() at Microsoft.Office.Server.Diagnostics.FirstChanceHandler.ExceptionFilter(Boolean fRethrowException, TryBlock tryBlock, FilterBlock filter, CatchBlock catchBlock, FinallyBlock finallyBlock)
For more information, see Help and Support Center at
http://go.microsoft.com/fwlink/events.asp.

These errors are related to profile synchronization issues. As WSS and MOSS has got different storage of User Profile data the "SYNC" job runs every 1 hour by default to synchronize data between the content databases. And Web Application stores these profile data. But for some entry in content databases of web application it still thinks that it has to open old SSP database. So now we have to clean the entries in following manner:

-Firtly get the GUIDs of all the web applications and content databases as thrown in the error long.
-Use this GUID to find the web application name because of which sync is going crazy. You can either use SharePoint Inspector or SharePoint Manager to find these details. Both can be downloaded from http://www.codeplex.com/spm and http://www.codeplex.com/spi
-Since I didn't prepared the web application's content database before changing the SSP hence all the issue started. So probably (I haven't tried yet) if we do this step before changing the association then we might not run into this situation. So now we have to fix the synchronization of content databases using "preparetomove" STSADM command. When the preparetomove operation is not run prior to moving the content database, synchronization can fail on a particular content database that has been moved to a new Web application. Synchronization is fixed for that content database by using this command. We will run this command for every web application and corresponding content database as follows:

stsadm -o preparetomove -site %WEBAPP% -oldcontentdb %GUID Of Content DB from Error Log%

-Once this command is run successfully we need to detach and reattach all the faulty content databases with their web applications again. You will do this by using "deletecontentdb" and "addcontentdb" STSADM commands as shown below:

stsadm -o deletecontentdb -url %WEBAPP% -databaseserver %DBSERVER% -databasename %DBNAME%
stsadm -o addcontentdb -url %WEBAPP% -databasename %DBNAME% -databaseserver %DBSERVER%

After doing this you can wait for next synchronization which occurs every hour by default or change the sync timing default value temporarily by using following command:

stsadm -o sync -synctiming "m:5" (This will run synchronization in every 5 minutes)

Wait for 5 minutes and check your error log. You will not see any reported errors.

Reset the sync timing back to default value of 1 hour
stsadm -o sync -synctiming "h:1"

Hopefully this will help you in resolving similar errors or issues.

Kunal

Tuesday, October 7, 2008

Change Default Index File Location

In a farm environment it will be usually a requirement to have the index file location on a separate drive and folder as opposed to the default location which is:

"C:\Program Files\Microsoft Office Servers\12.0\Data\Office Server\Applications"
You can set this path for an SSP by using the UI through Central Administration. But to set the default path for Office SharePoint Server Search Service and for WSS Search Service you will have to set the location through STSADM command.
Office SharePoint Server Search Service is configured using OSEARCH command:



If its not clear then read here:
stsadm -o osearch -defaultindexlocation e:\Data\MOSS_Search_Index

(By default, the search index will be located at this path on this server. For index servers, you can specify a different path when you create an SSP.
Note:
Changing the index location will reset the index. To move an index with a reset, use the noreset parameter of the Spsearchsensitive or Osearchsensitive operation)

Windows SharePoint Services Search Service is configured using SPSEARCH command:




If its not clear then read here:
stsadm -o spsearch -indexlocation e:\Data\MOSS_Search_Index
(Configures the search server that has the location of where the index resides)

You can also set this path for already created SSP using EDITSSP command:

If its not clear then read here:
stsadm -o editssp -title Sharedservices1 -indexlocation e:\Data\MOSS_Search_Index
(Configures the search server that has the location of where the index resides. This parameter is used in conjunction with the osearch operation. )
References:

Tuesday, September 30, 2008

Event ID 6482,7076,6398,27745

For past few days I have noticed errors in my event logs on the MOSS server. The errors were related to event ids 6482,7076,6398,27745. The description was:

Event Type: ErrorEvent Source: Windows SharePoint Services 3Event Category: General Event ID: 27745Date: 30/09/2008Time: 3:23:52 AMUser: N/AComputer: AUYXUAP310WBC32Description:The description for Event ID ( 27745 ) in Source ( Windows SharePoint Services 3 ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. You may be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following information is part of the event: #50071: Unable to connect to the database SharePoint_Config on SharePointSQLServer_Dev. Check the database connection information and make sure that the database server is running..

Event Type: ErrorEvent Source: Windows SharePoint Services 3Event Category: Timer Event ID: 6398Date: 30/09/2008Time: 3:23:52 AMUser: N/AComputer: AUYXUAP310WBC32Description:The Execute method of job definition Microsoft.Office.Server.Administration.ApplicationServerAdministrationServiceJob (ID 4dbd717a-6f8a-4595-8d03-6e21a6551257) threw an exception. More information is included below.
Not enough storage is available to complete this operation.

And similar errors regarding insufficient memory. There are many other suggestions on web but the one that fixed the errors for me was:

-For errors related to Event IDs 6482,7076,6398, I have to install hotfix 923028 available here:http://support.microsoft.com/kb/923028

-For error related to Event ID 27745, I have to stop and start the Windows SharePoint Services Timer service with following command:

net stop “Windows SharePoint Services Timer”
net start “Windows SharePoint Services Timer”

Saturday, September 27, 2008

Error When starting Windows SharePoint Search service

Last week I got stuck with few errors when starting WSS Search Service. Below are few errors that were thrown:



Error1:
Event ID: 10036
A database error occurred.
Source: Microsoft OLE DB Provider for SQL Server
Code: 6 occurred 1 time(s)
Description: [DBNETLIB][ConnectionOpen (Connect()).]Specified SQL server not found.

Error2:
Error Description: Could not access the Search service configuration database.


Few tips to avoid this kind of error:


  • Make sure the search service account has got DBCreator role on DB server. You can remove this role once the service is started.

  • Offcourse your normal Farm Admin service account also needs DbCreator and SecurityAdmin role.

  • I have read someone saying to use Named Pipes for remote connection. But this is not true it should work with TCP/IP connection as well. So in your SQL server make sure that your remote connection is enabled for either TCP/IP or Named Pipes or for both.

  • Make sure the DB Server name in your connection string is consistent in your farm for all other webapps, admin content config database etc etc..

  • Finally the solution that worked for me was that I was using "DB server name\Instance, port" as the connection string and this format of connection string uses Named Pipes. Unfortunately Named Pipes was disabled so I have to use an Alias of the DB server to use the TCP/IP connection. Also once the alias is setup for you by the DBA's you have to set it up on the MOSS server under SQL Server Client Configuration settings. You can also use server name if you are using default instance for TCP/IP.

I hope that makes sense. If anybody has any more suggestions or corrections to my suggestions then please do leave a comment.

Cheers,

Kunal

SharePoint Capacity Planning Tool

Not sure if some of you have already come across this tool. So instead of reading the whole capacity-planning documentation, you can get a rough idea of your hardware needs and farm topology design. Just enter information such as the number of users, locations, bandwidth and network topology, preferred hardware, and usage profiles. After you provide the tool with basic information about your organization, the tool provides a first approximation of the topology your organization needs.

Good tool for infrastructre guys!

Download Here or follow the link:

http://www.microsoft.com/downloadS/details.aspx?familyid=DBEE0227-D4F7-48F8-85F0-E71493B2FD87&displaylang=en

Sunday, September 14, 2008

Create Databases before deploying MOSS

In many organizatons there are certain policies and procedures where only DBA's can create databases. Now when installing MOSS 2007, the install creates the databases automatically that means they need to give the service account permissions to create database on DB server. This kind of breaks the organizational policy. Do you agree guys? No? Yes? Anyways these are the policies set by organization and we have to abide by them. So what do we do in these situations? Luckily there is a procedure where we can deploy MOSS using DBA-created databases. TechNet provides us with steps where DBA's can create databases on DB servers and Farm Administrators can configure them separately. Have a look at this TechNet article:

http://technet.microsoft.com/en-us/library/cc262869.aspx

Saturday, August 30, 2008

Friday, August 29, 2008

Burn ISO images on a Virtual CD

Found this great tool which allows us to mount ISO images as Virtual CD's. This saves us time and cost of buying CD's or DVD's. The tool is called as Virtual CD Control Panel. This tool allows you to mount any ISO image onto a virtual CD drive. The steps to install and configure this tool are included in the readme.txt file that comes with the download. You can download it from here:

http://download.microsoft.com/download/7/b/6/7b6abd84-7841-4978-96f5-bd58df02efa2/winxpvirtualcdcontrolpanel_21.exe

How good is that?? No need to buy a CD/DVD. Just mount the tool whenever you need to run the install.

Thursday, August 28, 2008

Attaching SPItemEventReceiver with a List Type

In my last post I have talked about writing an SPItemEventReceiver for fetching a workflow instance out of a Task item in a Task List type. Next step that comes to our mind is how we can attach this event receiver with a List. There are two ways in which you can attach your event receiver to a list type. One is through a feature: in elements.xml file you can write CAML and have Receiver attributes. another way is by using object model. I will explain you both the ways:

1) Feature way:

Create a feature.xml in the normal way as you do for any other feature. Here is the example:



"<"!--Created by Kunal Kochhar at 18/08/2008 10:21:18 AM--">"
"<"Feature Id="66D0E36C-4D48-46D0-90E9-7BFGHFBE4E3C" Title="Item receiver attacher" Description="This feature will attach event handler to a task item generated by Disposition workflow" Version="1.0.0.0" Scope="Web" Hidden="false" ImageUrl="CustomBranding.gif" xmlns="http://schemas.microsoft.com/sharepoint/"">"
"<"ElementManifests">"
"<"ElementManifest Location="elements.xml" /">"
"<"/ElementManifests">"
"<"/Feature">"



Now write the elements.xml file. This file will have Receivers tag. Read here more about Receivers element:

http://msdn.microsoft.com/en-us/library/ms431081.aspx

Let me show you the elements file:

'<'elements xmlns="http://schemas.microsoft.com/sharepoint/"'>'
'<'Receivers ListTemplateId="107"'>'
'<'Receiver'>'
'<'Name'>'TaskAdded'<'/Name'>'
'<'Type'>'ItemAdded'<'/Type'>'
'<'SequenceNumber'>'10043'<'/SequenceNumber'>'
'<'Assembly'>'assemblyname, [full four part]'<'/Assembly'>'
'<'Class'>'namespacename.classname'<'/Class'>'
'<'Data'>''<'/Data'>'
'<'Filter'>''<'/Filter'>'
'<'/Receiver'>'
'<'/Receivers'>'
'<'/Elements'>'



As you can see I am saying ListTemplateId=107 in the Receivers element. This id is the List Template Id for Tasks list type. You can refer to more list template ids here: http://msdn.microsoft.com/en-us/library/ms431081.aspx
Once you deploy and activate this feature on web it will attach your required event handler with all the existing tasks lists or any new ones that you create.

2) Lets see the second approach which is through code. The SPWeb object exposes list templates and contenttypes collections. You can retreive the required list template type and content type and can add your eventreceiver assembly in their eventreceivers collection. Here is an example to add it to a content type:

SPWeb web = SPContext.Current.Web;
SPContentType ct = web.ContentTypes["Tasks"];
SPEventReceiverDefinition receiverDef = ct.EventReceivers.Add();
receiverDef.Name = "Custom_ItemAdded";
receiverDef.Type = SPEventReceiverType.ItemAdded;
receiverDef.SequenceNumber = 10012;
receiverDef.Assembly = "assembly, [full four part assembly details]";
receiverDef.Class = "namespacename.classname";
receiverDef.Update();

I hope this will help some of you. If you have any queries in relation to this then please feel free to write to me.

Wednesday, August 27, 2008

Custom Timer Job

This post is mainly for me to remember on how to create a custom timer job. Thought of posting it anyways if anyone gets benefit out of it. Just saw this post by Andrew Connell on creating a custom timer job and then registering it in FeatureReceiver class:

http://www.andrewconnell.com/blog/articles/CreatingCustomSharePointTimerJobs.aspx

Monday, August 25, 2008

How to get workflow instance of a Task item

This post is about finding which workflow a task item is associated to. For example if you have a workflow setup on a document library which creates a task in a task list everytime that workflow is initiated and you want to do an action further when a task is created. Now this sounds pretty straightforward that you can attach an event handler with a Task list and do the needful. But remember that the particular Task list can be used for many workflows and you want to run your event only for a particular WorkFlow.

What you can do is, Task list exposes few properties which are hidden which tells the exact workflow information. The three properties which are of our interests are:

Workflow List ID (This represents the document library ID from where the workflow was initiated)
Workflow Item ID (This represents the document for which the work flow is initiated)
ows_WorkflowInstanceID (This is the workflow instance id of the workflow that has been setup for document library. This will help us to get the workflow type)

Let me show you a code snippet to get these details:


public override void ItemAdded(SPItemEventProperties properties)
{
try
{

SPListItem taskItem = properties.ListItem;

//Check if the item added is a Workflow related or not
if (taskItem["Workflow List ID"] != null)
{
SPWeb web = properties.OpenWeb();
Guid sourceListID = new Guid(taskItem["Workflow List ID"].ToString());
SPList sourceList = web.Lists.GetList(sourceListID, true);
int sourceListItemID = Convert.ToInt32(taskItem["Workflow Item ID"]);
SPListItem sourceListItem = sourceList.GetItemById(sourceListItemID);


//Get the workflow instance id from Task item
Guid taskWorkflowInstanceID = new Guid(taskItem["ows_WorkflowInstanceID"].ToString());

//Get the workflow object
SPWorkflow wf = sourceListItem.Workflows[taskWorkflowInstanceID ]

//Get the workflow association object
SPWorkflowAssociation wfAss = sourceList.WorkflowAssociations[wf.AssociationId];
try
{
//Check if the associated workflow is of type Disposition Approval
//This GUID will be same in every MOSS install
if (wfAss.BaseId.Equals(new Guid("dd19a800-37c1-43c0-816d-f8eb5f4a4145")))
{
//if the workflow is of type disposition then do your action
}

catch (ArgumentException argex)
{
}
}
}

}

}
catch (SPException spex)
{
}
catch (Exception ex)
{
}

}



You will notice that I am checking the base id of the Workflow Association object this gives us the workflow type which has been setup for the document library. In this case I am checking if the base id is of same type of the Disposition workflow. This GUID will be same in every MOSS install. Now in next post I will tell you how you can attach this event receiver with a Task list template type.

Tuesday, August 19, 2008

Event Handler Explorer Tool

I am sure lot of you must have had problems registering event handlers with list types or content types. There is a very good tool developed by Patrick Tisseghem called as
Event Handler Explorer. This tool allows you to browse and list instances and content types and to attach even handlers manually. This way you will be assured that the event receiver is attached properly.

Thought of sharing this great tool with every one :-)

http://www.u2u.info/SharePoint/U2U%20Community%20Tools/EventHandlerExplorer.zip

Cheers,
Kunal

Sunday, August 17, 2008

Upgrading WSS 2.0 Sites or Site Templates for WSS 3.0

Just came across this Solution Accelerator tool that helps you to upgrade Windows SharePoint Services 2.0 custom sites and templates. It also explains you on what steps and proceudres will be involved in this upgrade process.

http://www.microsoft.com/technet/solutionaccelerators/collaboration/default.mspx

Saturday, July 19, 2008

Join two SPList

QuickTip: Just saw a blog post by Mark Arned who explains how to join two lists based on an ID column. Mark has created a class which generetes a Join and returns you a List in a form of DataTable. The code can be downloaded from here:

http://code.msdn.microsoft.com/ListDataTable

Sahil Malik also shows you how to perform Joins on two SPList and to represent data in a parent/child format. Check here:

http://blah.winsmarts.com/2007-10-Performing_joins_between_SharePoint_lists.aspx

Monday, July 14, 2008

Hiding Item Level Menu from Edit Control Block

Ok, have tried and tried and couldn't find any solid solution to disable Edit Control Block menu from a specific list. There is HideCustomAction element that can be used to disable custom actions. But this cannot be used to disable ECB menu items because ECB menu items are generetaed by JavaScript function in Core.js. There is a very good article by Liam Cleary on various options for disabling ECB menu items but they are targeted to a complete site and cannot be done for a specific list.

There is a workaround which my colleague and me came up with. But this workaround is if you want to totaly disable ECB menu for a particular list. Actually there are couple of workarounds, but its upto you which one you wanna go with (depending upon the time constraint).

First is create your own custom web part which will list all the items using SPGridView and then you can customize it as per your requirement and place that web part within a PlaceHolderMain of your custom copy of AllItems.aspx page. For this you will have to remove the View from a List Definition. This is a time consuming process and I would recommend this only if you have to do lot of customization to your ListView Webpart on AllItems page.

Second option is to use a different column to disaply Title column of a list. For any list there are three types of Title columns. a) Title b) LinkTitleNoMenu c) LinkTitle

Now it must be clear from the name of these columns , LinkTitle column is the one that is displayed by default. This column has got JavaScript functions in the ListDefinition which brings ECB menu when rendered. LinkTitleNoMenu is the column that will just display a hyperlink to DispForm.aspx to view an item. And finally Title column is the one that will display just the title without any link or ECB menu.

Now you can set any of these columns in a view of either a List Definition or from the user interface. So ,this way you can decide if you want to have a ECB menu for a particular list or not.

Sunday, July 6, 2008

Setting Up SharePoint Project Environment

I have been working on setting up development environment in last two days and have come up with few tips which will definitely make our life easier while developing any sort of SharePoint project. These points are just my thoughts, so if some one has any good ideas then please do leave a comment and I will include in my posts.

I have used two tools and developed some code snippets. I will teach you in my next post on how to create these code snippets for feature.xml, elements.xml, onet.xml or any other xml code that you will need to make your development fast.

The tools that I have used are very familiar STSDEV and Andrew Connel's Project Utility Tool. Now you must have already seen, heard or used these tools. But since both the tools have their drawbacks, so we can use both these tools in sync to suit our needs. You can check above links to know in detail about these tools.

STSDEV: Gives us the flexibility of creating .ddf file, .wsp package, deploying assemblies to GAC, adding SafeControl to web.config on deployment and many build types. But one thing that needs to be done manually in STSDEV is creating folder structure. It does creates a basic RootFiles folder structure for you but if you have to add any more folders which has got a deep tree structure then you have to keep adding it manually. This is where Project Utility Tool plays its role.

Andrew Connel's Project Utility Tool : Also gives us benefit of creating .ddf file, .wsp package and more. But it has its drawbacks of not being able to handle any changes in .ddf file manually and some more stuff that STSDEV gives. So we will use this tool for generating the folder structure in a project that STSDEV has created.

I am not really commenting here on which is a good tool or a bad tool. I am really giving you an idea to utilise best of the outcomes of both tools and increase your efficiency and performance in developing custom SharePoint solutions. We really don't want to waste our time in doing repeated things when developing a SharePoint solution so why not use these beautiful tools which makes our life easier.

And also, I am not saying this is the best way to create and maintain Visual Studio projects for SharePoint solutions. If anybody has got any different idea then please do mention it here and share the knowledge among MOSS geeks :-)

Friday, July 4, 2008

Disabling unrequired Services in Windows 2003

I know this post is not relevant to SharePoint as such but will tell you on how you can improve the server security and performance.

There are around more than 100 services that run on a Windows 2003 Server. Some of these services might be useful and some may not be. So why not disable them rather than letting them chew your server resources. There are five basic service that you can quickly think of disabling. These are listed below:

1. ERSvc - Error Reporting Service (Used for reporting application crashes to Microsoft)

2. HidServ - Human Interface Device Access (Used for other smart devices, which you might not use on a server)

3. IsmServ - Intersite Messaging (Used for sending messages from server to server)

4. ScardSvr - Smart Card Access

5. LMHosts - TCP/IP NetBIOS Helper

Now these services are just the start. There is a list of other services that you can check, if you really need them. TechRepublic gives you such list. You can downlowd it from here.

Hope this might be helpful in some instances. Like you can disable such services on your VPC which you might be using as a development environment.

Tuesday, July 1, 2008

Custom Site Column in an existing OOTB List or ContentType

Today I will explain you on how to add a custom site column to an existing Out of the box (OOTB) List type or a content type. There will be instances during your project life cycle when you will want to provision a column to a particular List type or content type, for example you want to add a new column "Expert Comments" to a Wiki library. And you also want to provision this column to any new Wiki library created hereafter in the existing site.

Now for adding a new site column to custom list, you can add it directly when provisioning custom List Definition you can learn this here. But if you want to add a site column to already provisioned list you need to do it through object model.

Firstly you need to find the system content type for a List. Every list in in SharePoint uses a content type, either system content type or custom content type. You can view the content type hierarchy here. And you can find an associated content type for a system List using following lines of code in a console app:

using (SPSite site = new SPSite("http://devmoss/)"))

{

using (SPWeb web =
site.OpenWeb())

{

//List Content types in a web
foreach (SPContentType ct in web.ContentTypes)
{
Console.WriteLine(ct.Name);
}
Console.WriteLine("-------------------------");

//List Content types in a List
SPList list = web.Lists["Posts"];
foreach (SPContentType ctl in list.ContentTypes)
{
Console.WriteLine(ctl.Name);
}
Console.ReadLine();
}



Now once you know the content type of a List in which you wish to add a
custom column, you can use it add a new SPFieldLink to that SPContentType
object. Below is the sample code:




using (SPSite site = new SPSite("http://devmoss001/)"))
{
using (SPWeb web = site.OpenWeb())
{

try
{
string newColumn= "New Column";

//Construct required content type objects
SPContentType wikiContentType = web.ContentTypes["Wiki Page"];

//Check if the site column already exists
if (!web.Fields.ContainsField(newColumn))
{
//If the site column doesn't exist then create a new column and assign it to custom columns group
popularity = web.Fields.Add(newColumn, SPFieldType.Number, true);
SPFieldNumber fieldNum = (SPFieldNumber)web.Fields[newColumn];
fieldNum.Group = "Custom Columns";
fieldNum.Update(true);
}

if (!string.IsNullOrEmpty(newColumn))
{
//Get the field reference of new site column
SPFieldLink fieldLink = new SPFieldLink(web.Fields[newColumn]);

if (fieldLink != null)
{
try
{


//Add the site column to wiki content type
wikiContentType.FieldLinks.Add(fieldLink);
wikiContentType.Update(true);

}
catch (SPContentTypeSealedException ex)
{
}
catch (SPContentTypeReadOnlyException ctEx)
{
}
}

}

}

catch (SPException ex)
{
//Write to Logger
}


}
}


I hope that will be of some help to you. If you have any questions related to this concept then feel free to write to me.

Saturday, June 28, 2008

SharePoint Developers WebCasts

If you are looking for live demos, virtual labs, sample codes and more SharePoint concepts then visit this site. Try to install SilverLight and then see the site to experience something new :-)

http://www.mssharepointdeveloper.com

Watch this site for updates.

Wednesday, June 11, 2008

The virtual path '/_catalogs/masterpage/default.master' maps to another application, which is not allowed.

I have seen lot of users having following error when adding a custom web app in layouts folder and when trying to use default.master page for custom web app pages.

Exception Details: System.ArgumentException: The virtual path '/_catalogs/masterpage/default.master' maps to another application, which is not allowed.

Firstly make sure that you have created your web app correctly and have done all the configurations or settings. For details on doing this please check this great blog post by Roni

And finally if the error occurs then try commenting out the line
'<'authentication mode="Windows" /'>'
in your web app web.config file. This solution has fixed the error for me and for my friends.

Saturday, May 31, 2008

MCTS WSS 3.0

It was a great week! I have now successfully completed my WSS 3.0 Application Development
(70-541) certification. Few preparation tips:

-Read Inside WSS 3.0 by Ted Pattison . This is a great book and will give you a very good understanding of the concepts Windows SharePoint Services 3.0.
-I have completed all the Microsoft E-Learning courses mentioned in the program guide of
70-541. There are two collections 5385 and 5392. These collections will help you in understanding concepts further.
-Having hands on experience for 6 months on a project will help you for sure.
-Understand complete SharePoint object model.
-Try creating Site Definition manually, understand Onet.xml completely.
-Play with features, web parts and workflows.
-A little understanding of deployment procedure using solution packages.

Wednesday, May 21, 2008

Quick Tip: Web Service to SharePoint Data

If you want to use web services to manipulate data on your SharePoint site, you must always allow unsafe updates on your site and then disable unsafe updates after making changes.

Want to know more on AllowUnsafeUpdates, check this

Wednesday, April 30, 2008

Exception Handling

In Sharepoint specially when writing WebParts and Event Handlers exception handling should be done properly else you get mixed results. Try to catch exceptions in two parts one is SPException type and another is SecurityException type.

There is a very good tool called as FxCop. This application checks for if the exception haldings and naming conventions are as per Microsoft Stadards or not. Want to know more about FxCop? Go Here!

Monday, April 28, 2008

Finally REMIX

Finally Microsoft REMIX is in Australia too. Here you will get to see next generation websites developed using Silverlight 2, Expression 2, IE 8 and more. You can register here at REMIX


Editing web.config Programmatically

Today after finishing the webpart development when the time came to deploy them, I realised that everytime I deploy these webparts on another server I have to add SafeControl in web.config manually again and again. Did some research and found some good articles. SPWebConfigModification is the class that we can use to modify the web.config file.

Mark Wagner has dotted down some good best practices to do this. Check here

Ted Pattison has also written some great details about the complete process to do it and he has also uploaded a sample feature to do this. Check here

And if you are still not satisfied then read more information about SPWebConfigModification on msdn

Link to an item when running SPSiteDataQuery

Many a times we will need to run SPSiteDataQuery on a list to get the results from a sitecollection. Now once we have retreived the results from the query we need to get the url of each item. There is a hidden column "EncodedAbsUrl" which consists of complete URL to an Item. For some reason accessing this column doesn't give us the complete URL that we need (I don't know why). But there is another trick to get the URL of an item. There is another hidden column "FileRef" in each list. This column data has got the URL with the item ID concatenated to it, something like this:

row["FileRef"] = 1;#Popular Wiki/How To Use This Wiki Library.aspx

**row is from the datatable returned when you run web.GetSiteData(query) and query is the constructed SPSiteDataQuery.

We can retreive the URL part from it and construct the complete link from the root site. Something like this:

string url = row["FileRef"].ToString().Substring(row["FileRef"].ToString().IndexOf("#") + 1);

string finalUrl = site.MakeFullUrl(url);

You can read more about MakeFullUrl() method here msdn

Tuesday, April 15, 2008

Creating WebPart instances in Custom Site Definitions

Cool Stuff! I have just found or I should say "I just came to know" that we can create a webpart instance on the default page of a site right in the Site Definition. Consider a scenario where you are having a Custom Site Definition and you wish to put some standard webparts for all the users when a site is created using this Site Definition->Site Template. You can do this in two ways one is the through the object model using SPLimitedWebPartManager class and another is via CAML in site definition. I will explain via CAML way in this post:

If you have seen my previous post on Site Def architecture, we have got Modules node:

<Modules> <Module Name="Default" Url="" >
<File Url="default.aspx" NavBarHome="True" Type="Ghostable"> </File>
</Module>
</Modules>

Now under File node we have <AllUsersWebPart> node available. This is the key to add any webpart instances. Below is the example:

<AllUsersWebPart WebPartZoneID="Right" WebPartOrder="0">
<![CDATA[
<WebPart xmlns="http://schemas.microsoft.com/WebPart/v2"
xmlns:iwp="http://schemas.microsoft.com/WebPart/v2/Image%22&gt; <Assembly>Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly> <TypeName>Microsoft.SharePoint.WebPartPages.ImageWebPart</TypeName> <FrameType>None</FrameType>
<Title>Home Page</Title> <iwp:ImageLink>/_layouts/images/CONTACT.PNG</iwp:ImageLink> </WebPart> ]]>
</AllUsersWebPart>

Site Definition Architecture

If some one is looking for a basic site definition template or skeleton or wants to see what site definition consists of then please check below. It has also got XML namespace for SharePoint which will allow the intellisense when you eidt the file in Visual Studio:

You will have to remove single quote ( ' ) from the opening and closing angle brackets to use this. Sorry for this as they were being removed when publishing.

'<'?xml version="1.0" encoding="utf-8"?'>'
'<'Project Title="My Site Definition" Revision="0" ListDir="Lists" xmlns:ows="Microsoft SharePoint" xmlns="http://schemas.microsoft.com/sharepoint/"'>'
'<'NavBars /'>'
'<'DocumentTemplates /'>'
'<'Configurations'>'
'<'Configuration ID="-1" Name="NewWeb" /'>'
'<'Configuration ID="0" Name="Default"'>'
'<'Lists'>'
'<'/Lists'>'
'<'Modules'>'
'<'Module Name="Default" /'>'
'<'/Modules'>'
'<'SiteFeatures /'>'
'<'WebFeatures /'>'
'<'/Configuration'>'
'<'/Configurations'>'
'<'Modules'>'
'<'Module Name="Default" Url="" '>'
'<'File Url="default.aspx" NavBarHome="True" Type="Ghostable"'>''<'/File'>'
'<'/Module'>'
'<'/Modules'>'
'<'/Project'>'

Web Part Class/Assembly Details

Many times you would like to know the assembly details and class name of a webpart. Now you can ask why you need to know these details. This is why! for example you are trying to dynamically trying to add some webparts on a page. To add these webparts you will first have to load the assembly and then have to create an instance of that webpart class through reflection. Now to load these assemblies and to create instance of webparts from webpart gallery you need to know there full 4 part assembly name and class name.

This is how! Try to add this webpart on your page through EditPage action. Once you have added you can now Export this webpart and open the .webpart file in a notepad. There you will see something like this:

'<'assembly'>'Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'<'/assembly'>' '<'typename>Microsoft.SharePoint.Portal.WebControls.QuickLinksMicroView'<'/typename'>'


Here Typename is the class name of the webpart. And this is for a My Links webpart. This will come handy manytimes when the name of Webpart class is different from the name in webpart gallery (Which is the case most of the time)

Finally got started

"I believe knowledge sharing is key to knowledge gain"

Hi All,

Finally bolgger world has pulled me to start my own blog. I have been thinking this for so long and now my self motivation has forced me to create my knowledge sharing place. I have created this blog to share any issues , solutions, tricks etc..that I find when working on MOSS projects. I hope this information will be helpful to some of you and will save some time.

Will try my best to actively post any solutions or tips I find or come across.

Oh yeah! and just to start with - tomorrow is a SharePoint UserGroup happening in Canberra. Patrick Tisseghem is in town and will be delivering a session on Customizing Search page and results. Check this: http://www.sharepointusers.org.au/Canberra/default.aspx

I am defi going for this session and will try to share some information on here.