Tuesday, April 26, 2011

Different types of application with Sharepoint Object Model

SharePoint object model is a .NET-based API to SharePoint components. Or in simpler language you can say SP OM is a way to access Sharepoint components from your custom application(console,web etc.).

Thought I don't encourage anyone to use it over Sharepoint web services but there may be situations where you will have to use it. Sharepoint web services are the best way to deal with any sort of Sharepoint issues from outside of Sharepoint. And before using SP OM keep it in mind that The object model can be used when the application will run on the server where SharePoint is installed or in assemblies that are run within a site (such as a Web Part).

Here I am showing how to use SP OM in two types of application, Console and Web.

First console.
1. Create a console application and add reference to Microsoft.Sharepoint to your project. In case of SP2010 you will find it in "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\Microsoft.SharePoint.dll" and in case of SP2007 you will find it in "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\Microsoft.SharePoint.dll"

2. Add the following code to your project.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;

namespace test
{
class Program
{
static void Main(string[] args)
{
string siteStr = "<SP Site URL>";
SPSite tempSite = new SPSite(siteStr);
SPUserToken systoken = tempSite.SystemAccount.UserToken;
using (SPSite site = new SPSite(siteStr, systoken))
{
using (SPWeb web = site.OpenWeb())
{
//right now, logged in as Site System Account
Console.WriteLine("Currently logged in as: " + web.CurrentUser.ToString());
Console.Read();
}
}
}
}
}




2. Now go to the "Properties" window of the project and select "Application" tab. Change the "Target Framework" to ".NET Framework 3.5". Now go to "Build" tab and change the "Platform Target" to "x64".

Now run your application. You should see something like "Currently logged in as: SHAREPOINT\system".

For Web appliaction.

1. Create a ASP.NET web site and add the following code in your .aspx page's code behind. Add Microsoft.Sharepoint like before.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string siteStr = "http://dacsvm0021/my/personal/SSO/";
SPSite tempSite = null;
SPSecurity.RunWithElevatedPrivileges(delegate(){
tempSite = new SPSite(siteStr);
});

SPUserToken systoken = tempSite.SystemAccount.UserToken;
using (SPSite site = new SPSite(siteStr, systoken))
{
using (SPWeb web = site.OpenWeb())
{
Label1.Text = "Currently logged in as: "+web.CurrentUser.ToString();
}
}

}
}



As you can guess I have created a Label "Label1" in my page.

2. Create a web site in IIS. Now here is a small trick. While creating the site do not create a new application pool for your site, rather use the application pool of your Sharepoint site.

3. Now deploy your site to your IIS site.

Now if you browse the site you should see something like "Currently logged in as: SHAREPOINT\system".

After doing all these you still may have issues with Object Model. One popular but unauthenticated suggestion is to run all your application in "Administrator" mode. If still you have issues then beg help from Allah!

Saturday, February 26, 2011

Install Sharepoint 2010 in Windows 7

If you google with the title of this post you will see many people struggling with this and everyone with their own solution. Unfortunately none of the solutions worked for me. Here I am describing the steps I followed to do this.

Step 1. As you start your installation you will soon see the following error. Pretty disheartening :(



Now to handle this issue open the config.xml file from "\Files\Setup" folder. Add the following line in the <Configuration> section of this file.


<Setting Id="AllowWindowsClientInstall" Value="True"/>



Now your installation will proceed. Except this modification installation will not start in Windows 7.

Step 2. Now as your installation go on you will see the ‘non-supported for production’ notice:



I hope I don't have to explain why this message is prompted. No one should try a production in Windows 7 fro sharepoint.

Step 3. Now you installation will be finished smoothly. But you may face the next hurdle during SharePoint Products Configuration Wizard. If "Windows identity foundation pack" is missing in your machine you will see the following error

Could not load file or assembly 'Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.

To resolve this download the pack from http://www.microsoft.com/downloads/details.aspx?FamilyID=eb9c345f-e830-40b8-a5fe-ae7a864c4d76&displaylang=en and install it in your Windows 7 machine.

Step 4. If "Chart Control" is missing in your windows 7 machine then you will get the following error.

An exception of type Microsoft.SharePoint.Upgrade.SPUpgradeException was thrown. Additional exception information: Failed to call GetTypes on assembly Microsoft.Office.Server.Search, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c. Could not load file or assembly 'System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.

To resolve this issue download it from http://go.microsoft.com/fwlink/?LinkID=122517 and install it.

Ok, all these should be enough. If you still are fighting with this please drop a comment, I shall try to answer with the solution.

Sunday, March 14, 2010

Custom Web Service in MOSS 2007

It was a bad time for me when I was trying to run custom web service in Sharepoint. I was trying and trying and getting weird situations again and again. Anyway,finally it was done and I want to share it with others to save some of their time.

Step 1. Create an ASP.NET Web Service Application in VS 2008. Rename your Service1.asmx file and class name according to your desired name both in .cs file and in markup file.

There are no step 2 and 3, go to step 4 :)

Step 4. Create a strong name for the dll of your project. In Solution Explorer, right-click the web service project, and in the Properties dialog box, click Signing, select Sign the assembly, and select in the box and create a new strong name key file. Now build the project.

Step 5. Copy the .asmx file to C:\Inetpub\wwwroot. Open the file and delete this portion -


CodeBehind="YourService.asmx.cs"

Go to GAC, right click on your assembly and copy the publick key from properties. Your final markup looks like this.

<%@ WebService Language="C#" Class="YourService.YourService, YourService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=615f0967ce2cd86a" %>

Step 6. Now you have to create .disco and .wsdl files and modify them. There are two ways to do this - creating and modifying manually or using some tool. I prefer the second way but both are explained here.

First Method -
>Run the command in cmd -

set path=%path%;"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin";.

> Now run this command in cmd -

Disco http://localhost/YourService.asmx

YourService.disco and YourService.wsdl files will be created.

>To register namespaces of the Windows SharePoint Services object model, open both the .disco and .wsdl files and replace the opening XML processing instruction -- -- with instructions such as the following:


<%@ Page Language="C#" Inherits="System.Web.UI.Page"%><%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0,Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Import Namespace="Microsoft.SharePoint.Utilities" %> <%@ Import Namespace="Microsoft.SharePoint" %><% Response.ContentType = "text/xml"; %>

>In the .disco file, modify the contract reference and SOAP address tags to be like the following example, which replaces literal paths with code generated paths through use of the Microsoft.SharePoint.Utilities.SPEncode class, and which replaces the method name that is specified in the binding attribute:


<contractref ref="&lt;%" wsdl="" output="" docref="&lt;%" xmlns="http://schemas.xmlsoap.org/disco/scl/"><soap address="&lt;%" q1="http://tempuri.org" binding="q1:FilesSoap" xmlns="http://schemas.xmlsoap.org/disco/soap/"><soap address="&lt;%" q2="http://tempuri.org" binding="q2:FilesSoap12" xmlns="http://schemas.xmlsoap.org/disco/soap/">

> In the .wsdl file, make the following, similar substitution for the SOAP address that is specified:


<soap:address location="&lt;%">

>Make the following substitution for the SOAP12 address:


<soap12:address location="&lt;%">

> Rename both files in the respective formats YourServicedisco.aspx and YourServicewsdl.aspx so that your service is discoverable through SharePoint.

Second Method -
>Go to the link http://www.codeproject.com/KB/XML/wss_web_service_helper.aspx and download the tool.

>Use the tool to create YourServicedisco.aspx and YourServicewsdl.aspx files.

Step 7. Now you copy YourServicedisco.aspx,YourServicewsdl.aspx and YourService.asmx files to _vti_bin virtual directory which maps physically to the C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI directory, which contains the default Web service files used in Windows SharePoint Services.

Step 8. To make your Web service discoverable in Visual Studio as a Web service alongside the default Windows SharePoint Services Web services, open the spdisco.aspx file located in C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI and add the following code, specifying the .asmx file for your Web service.


<contractRef ref=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(spWeb.Url + "/_vti_bin/YourService.asmx?wsdl"), Response.Output); %>
docRef=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(spWeb.Url + "/_vti_bin/YourService.asmx"), Response.Output); %>
xmlns=" http://schemas.xmlsoap.org/disco/scl/ " />
<discoveryRef ref=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(spWeb.Url + "/_vti_bin/YourService.asmx?disco"),Response.Output); %>
xmlns="http://schemas.xmlsoap.org/disco/" />

Step 9. Now go to the link http://yoursite:port_number/_vti_bin/yourservice.asmx. You will see the functions of web service listed in the page.

Step 10. Click a function to see it's Soap. You have to use this soap to call the web service method and retrieve it's returned value.

Here I am giving a jquery example of calling and displaying the data using the soap.

Soap Request

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<HelloWorld xmlns="http://tempuri.org/" />
</soap:Body>
</soap:Envelope>


Soap Response

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<HelloWorldResponse xmlns="http://tempuri.org/">
<HelloWorldResult>string</HelloWorldResult>
</HelloWorldResponse>
</soap:Body>
</soap:Envelope>

Just create a Content Editor web part and paste this code to call the Web Service.



<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
function btnClicked(){

var soapEnv =
"<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>\
<soap:Body>\
<NewMethod xmlns='http://tempuri.org/'>\
<test>"+'Test'+"</test>\
</NewMethod>\
</soap:Body>\
</soap:Envelope>";

$.ajax({
url: "_vti_bin/SPWSData.asmx",
type: "POST",
dataType: "xml",
data: soapEnv,
complete: processResult,
contentType: "text/xml; charset=\"utf-8\""
});
}

function processResult(xData, status) {
alert(status);
$(xData.responseXML).find("NewMethodResult").each(function()
{
var data = $(this).text();
alert(data);
});
}
</script>

<input type="button" onclick="btnClicked()" value="Click"/>

Ok,this is all about creating and hosting custom web service in MOSS 2007