Pages

Friday, April 24, 2009

Create a Deployable Custom SharePoint Web Service

So, you want to expose some SharePoint functionality to a web service, and you want to make sure it’s deployable. This is how we do it!

You have 3 major steps:

1. Build your web service
2. Set up the SharePoint Solution
3. Add the Solution to SharePoint and Deploy

Requirements before your start:
- Visual Studio
- MakeCab.exe
- Access to the SharePoint server where you want to deploy this service

Follow along below…



Build your web service

This is a great walkthrough for creating a custom sharepoint webservice: http://msdn.microsoft.com/en-us/library/ms464040.aspx

A
few supplemental notes:

- if you plan on exposing SharePoint functionality, you will have to add a reference/using statement to Microsoft.SharePoint

- when changing your .asmx file, make sure you get the fully qualified name of your class and dll. For example:
<%@ WebService Language="C#" Class="CustomWebService.Service, CustomWebService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4eef54b119a62de3" %>

- Disco.exe is available in the Visual Studio 2008 > Visual Studio Tools > Visual Studio 2008 Command Prompt

- make sure you go to the _layouts directory where you’ve copied the .asmx when you run disco.exe

At the end of this process you should have:

- Access to http://myserver/_vti_bin/yourservice.asmx
- a solution like this:

image
- these files in C:/Program Files/Common Files/Microsoft Shared/web server extensions/12/ISAPI

image

- and, your CustomWebService.dll in the GAC



Set up the SharePoint solution

First, get all your necessary files into your Class Library project

1. Create folders to hold your files – in the Class Library project you created, right click > Add New > Folder, and create:

DeploymentFiles – to hold all the SharePoint solution generation files
ISAPI – to mimic the final location of all your web service files
Assembly – this is a personal preference of where I like to have my dlls deployed. If you use this, make sure you change the project properties to write the dlls here.

2. Move all the web service files into the ISAPI folder

image

3. Create the SharePoint Solution generation files in the DeploymentFiles folder:

- BuildSharePointPackage.ddf – this file tells makecab.exe which files in the solution will be included in the .WSP file and in what structure

; *** .ddf file for generating SharePoint solution.
;
.OPTION EXPLICIT ; Generate errors
.set DiskDirectoryTemplate=CDROM ; All cabinets go in a single directory
.Set CompressionType=MSZIP;** All files are compressed in cabinet files
.Set UniqueFiles="ON"
.Set Cabinet=on

DeploymentFiles\manifest.xml
Assembly\CustomWebService.dll

.Set DestinationDir=ISAPI
ISAPI\CustomWebService.asmx
ISAPI\CustomWebServicedisco.aspx
ISAPI\CustomWebServicewsdl.aspx

;***End

When you open up the CAB version of the WSP file, it will look like this:

image

- BuildSharePointPackage.Targets – tells Visual Studio how to call MakeCab.exe to create the WSP file

<Project DefaultTargets="BuildSharePointPackage" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MakeCabPath>"C:\Windows\System32\MAKECAB.EXE"</MakeCabPath>
</PropertyGroup>
<Target Name="BuildSharePointPackage">
<Exec Command="C:\Windows\System32\MAKECAB.EXE /F DeploymentFiles\BuildSharePointPackage.ddf /D CabinetNameTemplate=$(MSBuildProjectName).wsp /D DiskDirectory1=WSPs\$(Configuration) "/>
<Exec Condition=" '$(Configuration)$(Platform)' == 'DebugAnyCPU'"
Command="$(MakeCabPath) /F DeploymentFiles\BuildSharePointPackage.ddf /D CabinetNameTemplate=$(MSBuildProjectName).cab /D DiskDirectory1=WSPs\$(Configuration)"/>
</Target>
</Project>

Please not that the <MakeCabPath> should point to wherever you have MakeCab.exe installed.

- manifest.xml – this files tells the WSP what to do with the files when the solution is deployed

<?xml version="1.0" encoding="utf-8" ?>
<Solution xmlns="
http://schemas.microsoft.com/sharepoint/"
SolutionId="70DA8F86-312E-11DE-9B70-CEFF55D89593"
DeploymentServerType="WebFrontEnd"
ResetWebServer="TRUE">

<RootFiles>
<RootFile Location="ISAPI\CustomWebService.asmx"/>
<RootFile Location="ISAPI\CustomWebServicedisco.aspx"/>
<RootFile Location="ISAPI\CustomWebServicewsdl.aspx"/></RootFiles>
<Assemblies>
<Assembly DeploymentTarget="GlobalAssemblyCache" Location="CustomWebService.dll">
</Assembly>
</Assemblies>
</Solution>

Lets break this part down, as it is important.

- SolutionId – get a new GUID to identify your solution
- <RootFiles> – this tag tells the solution to put files at the root lever, the 12 Hive
- <RootFile> – one tag for each file,the location property tells where in the WSP we are getting the file to place at the Root. B/c we put the the file into the WSP at the ISAPI path, the manifest will also deploy the file to the ISAPI path from the root location.
- <Assembly> – this tag will place the dlls in the appropriate location. The DeploymentTarget set to “GlobalAssemblyCache” will put the dll in the GAC.

So, now your solution should look like this:

image

4. Update the .csproj file to user MakeCab to generate the WSP

- Unload the project and edit the .csproj file

Find the line:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

Below there, enter the following lines:

<Import Project="DeploymentFiles\BuildSharePointPackage.targets" />
<Target Name="AfterBuild">
<CallTarget Targets="BuildSharepointPackage" Condition=" '$(Configuration)$(Platform)' == 'DebugAnyCPU' " />
</Target>


Save and Reload the project.

Build the project and you should have WSP files in a WSPs folder in the project. Make sure you include this folder in your project.



Add the WSP to SharePoint & Deploy!

use stsadm to add the solution to the central admin solution store

from the 12 hive/bin, open a command window and run the following command:

stsadm –o addsolution –filename [Location of your .wsp file]

Then go to Central Administration > Operations > Solution Management

You should see your wsp in there. Click the name and deploy it immediately.

Verify that :

- your dll is in the GAC
- your .asmx, xxxwsdl.aspx, and xxxdisco.aspx are in the 12 hive/ISAPI folder
- and that you can navigate now to http://yourserver/_vti_bin/yourservice.aspx

And you are finished! congrats!

Thursday, April 16, 2009

NEVER EVER type: stsadm –o uninstall !!! (yes, we need at least 3 !s for this)

Just a little warning for you guys:



stsadm –o uninstall will uninstall SHAREPOINT from your server with NO WARNING.


That is bad. very very very bad.

funny enough, when you type stsadm –help, it doesn’t even list this command.


WOW.



IF you should happen to accidently type this when, say, trying to uninstall a feature and accidently hitting enter too soon --(Hypothetically speaking of course…) you are pretty much in for a world of hurt.


You will have to re-install sharepoint,reconfigure Central Admin and SSP(s) and then re-attach your content db.

The difficulty here is that your content db will no longer be getting the profile synch b/c it is still associated with the old SSP in the database, even though through the UI, you can see that your web app is correctly associated with the new SSP after reinstall. I haven’t quite figured out how to fix this. Any insight into how to fix the association of a content db to an SSP would be much appreciated.

One amazing thing I did find, however, is that once site was up and running again, workflows seem to continue without a hiccup. I’m guessing this has something to do with the dehydration/rehydration of the workflow when it is waiting for the next step to happen.

Hope none of you will ever run into this!

Using SPQuery to find an item in a doc library with folders

if you know the actual folder where your item is:

SPQuery query = new SPQuery();

query.Folder = [insert folder path];

But what do you do if you have no idea what folder it is in?

Luckily the answer is just as easy:

 

http://sharepointlive.blogspot.com/2008/12/issue-spquery-doesnt-return-items-from.html

query.ViewAttributes = "Scope='RecursiveAll'";


 



will search through all items in the doc library.



Sweet.