Sunday, June 8, 2008

Create multiple Ajax-enabled Web Sites in Windows Sharepoint Services and MOSS 2007

Introduction
The goal of this post is to point out the key that will allow you to use Ajax for multiple sites in Windows SharePoint Services or MOSS 2007. Our team met the problem. We had several SharePoint Web Sites that had to exchange informations with an Ajax Web Service, and we couldn't use the SPContext object in the web service code because it was always instantiated the site collection top level site SPContext object.
We used a temporary solution passing the SharePoint Web Site GUID as a parameter to the Web Method.
Thanks to Daniel Larson that answered to a comment I posted on his blog, we found the solution. You may find it in a more complete version in the chapter 5 of his book written with Ted Pattison:

Inside Microsoft Windows SharePoint Services 3.0

Tutorial

To make a clear demonstration I will customize the WsAjaxEnabledWSSApplication I created in a previous post:

Integrate ASP.NET Web Service based AJAX with MOSS 2007 or Windows SharePoint Services 3.0

1 - Adding a new aspx page that will display the Title of the web site.

I add to the solution a new aspx page that will display the Title of the web site that is invoking the Ajax Web Service. This Title must be returned by the Ajax Web Service.



2 - Adding a new Web Method that will return the Title of the web site.

I add to the web service a new Web Method in order to get the Title of the Web Site that is invoking Web Service:
        [WebMethod]
        public string GetSPWebTitle()
        {
            return (SPContext.Current.Web.Title);
        }


3 - The AjaxRetrieveSPWebTitle.aspx page inline code

And now, the most interesting, the .aspx page inline code :
<%@ Assembly Name="Microsoft.SharePoint.ApplicationPages, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Page Language="C#" MasterPageFile="~/_layouts/application.master" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Import Namespace="System.Globalization" %>

<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">

    <script runat="server">
    
        private const string WebInitScriptKey = @"WSAjaxEnebledWSSApplication.AjaxRetrieveSPWebGUID.aspx";
        private const string WebInitScriptFormat = @"window.spWebUrl = '{0}';";

        public void Page_Load(object sender, EventArgs e)
        {
            string webInitScript = string.Format(CultureInfo.InvariantCulture, WebInitScriptFormat, SPContext.Current.Web.Url);
            this.Page.ClientScript.RegisterClientScriptBlock(typeof(System.Web.UI.Page), WebInitScriptKey, webInitScript, true);
        }
    </script>

    <script type="text/javascript">
        function getMyWebTitle(){
            WsAjaxEnabledWSSApplication.HelloWorldService.set_path(window.spWebUrl + "/_vti_bin/AjaxWebService/HelloWorldService.asmx");
            WsAjaxEnabledWSSApplication.HelloWorldService.GetSPWebTitle(OnComplete, OnTimeOut, OnError);
        }
        
        function OnComplete(args){
            document.getElementById("divWebServiceReturn").innerText=args;
        }
        
        function OnTimeOut(args){
            alert("Time Out");
        }
        
        function OnError(args){
            alert("Error");
        }
    </script>

    <asp:ScriptManager ID="ScriptManager1" runat="server">
        <services>
                <asp:ServiceReference InlineScript="true" Path="~/_vti_bin/AjaxWebService/HelloWorldService.asmx" />
         </services>
    </asp:ScriptManager>
    <br />
    <br />
    <input type="button" value="Get myWeb Title" onclick="JavaScript:getMyWebTitle();" />
    <br />
    <br />
    <span>Ajax Web Service returned that web site Title: </span>
    <div style="display: inline; color: Black" id="divWebServiceReturn">
    </div>
</asp:Content>

4 - Summary.

So the Key point is :
to set the path correctly before calling the service
   WsAjaxEnabledWSSApplication.HelloWorldService.set_path(window.spWebUrl + "/_vti_bin/AjaxWebService/HelloWorldService.asmx");

And to set the path, I used the JavaScript property as used by Daniel Larson and Ted Pattison in SharePoint AJAX Toolkit:
   window.spWebUrl 


5 - Testing

I am now creating a new subsite, mySubsite1.
As my .aspx page is an application page, for any site in my Site Collection that will be using that page, I will get its Title :





No comments: