Home > SharePoint > Call Sharepoint web services from javascript and c# code

Call Sharepoint web services from javascript and c# code

2011/10/22

In the previous post we have seen that using the GetAttributeFromItemTable function we can read the current item ID, but this function cannot read other fields value of the current item.

We could use some JQUery trick to read other cells values, but the views can be changed causing errors in our jQuery code; and consider that we could read on our page an obsolete value, someone could have changed the data in the meantime.

So , giving the fact that we can’t access the server functionalities as in SharePoint 2010, it is necessary to use the SharePoint web services: this will can make the future migration to MOSS 2010 a nightmare, but we ever hope that we will avoid this task…

Another task could be to request data from MOSS from a client application not on the server, for example a Windows Forms app .

So in this post i show the same task , get the Title and the File name fields from a document library having the ID of the item, by C# code and from Javascript.

This is our sample item with ID 426:


First example, use the MOSS web services from a Windows Forms app:

Create in Visual Studio (for this sample we use Visual Studio 2008) a windows form application, using .NET 3.5

Add Service Reference->Advanced->Web reference

Here we can browse Web services on the local machine if we are developing on the server, or insert the web address directly.

The web services on MOSS are numerous, and is better to read the documentation on MSDN to get an idea before starting.

Tipically in your MOSS there can be more than one web application with subwebs, in every web app one or more Site collection: the web services are the same, but is necessary to give the correct path in order to reach the List or Document library you intend to work with, otherwise you can get strange errors as “Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).”

In the web services list we need to use the GetListItems method.

These web services use CAML, In order to write the correct syntax is better to use some software as Stramit CAML viewer 2007 or U2U CAML Query Builder.

The Stramit does not have a wizard for query construction as the U2U, but it shows the internal fields names (the ones with “ows_” prefix) to read when is returned the result of our query .

U2U show the fields list, the operators list so we can construct the query:


Assuming that we have called srv2008moz our proxy class in the visual studio project we see


Place a button and then in the click event :

private void button1_Click(object sender, EventArgs e)
{
    string strTest = string.Empty;
    // change the username, password and domain with the value of a user who has permission to the list
    srv2008moz.Lists obj = new srv2008moz.Lists();
    obj.Url = "http://srv2008moss:1010/intranet/Discovering/_vti_bin/lists.asmx";
    // note that we can change the Url of the proxy by code
    obj.Credentials = new System.Net.NetworkCredential("administrator", "password", "domain");
    XmlDocument xmlDoc = new XmlDocument();
    XmlNode ndQuery = xmlDoc.CreateNode(XmlNodeType.Element, "Query", "");
    XmlNode ndViewFields = xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields", "");
    ndViewFields.InnerXml = "<FieldRef Name=\"Title\" />";
    ndQuery.InnerXml = "<Where><Eq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">426</Value></Eq></Where>";
    XmlNode ndListItems = obj.GetListItems("CEO Documents", null, ndQuery, ndViewFields, null, null, null);
    XmlNamespaceManager nsManager = new XmlNamespaceManager(ndListItems.OwnerDocument.NameTable);
    nsManager.AddNamespace("z", "#RowsetSchema");
    nsManager.AddNamespace("s", "uuid:BDC6E3F0-6DA3-11d1-A2A3-0AA00C14882");
    nsManager.AddNamespace("dt", "uuid:C2F41010-65B3-11d1-A29F-00AA00C14882");
    nsManager.AddNamespace("rs", "urn:schemas-microsoft-com:rowset");
    XmlNodeList nodes = ndListItems.SelectNodes("rs:data/z:row", nsManager);
    strTest = nodes[0].Attributes["ows_Title"].Value;
    MessageBox.Show(strTest);
}

The result:


For the viewfields we use only Title in the sample, but we can add <FieldRef Name=\”Fieldname\” /> strings for every field we need in the ndViewFields string.

In ndQuery we can see our query string generated in U2U.

In this case we are secure to have only one result, if we have more results we can use the code:

foreach (XmlNode node in nodes)

{

strTest += node.Attributes[“ows_Title”].Value;

}

Second example, from javascript:

In this case we don’t have objects as XmlDocument, or in any case is not appropriate to use Internet Explorer only functionalities.

In this case we pass a string using Jquery, assuming that we have a custom item menu for a document library :

var strCtxHttpRootAR20111020;
 
function Custom_AddDocLibMenuItems(m, ctx) {
    var strImagePath = ctx.imagesPath + "UPDATEPAGEVARIATION.GIF";
    if (currentItemFileUrl == null)
        currentItemFileUrl = GetAttributeFromItemTable(itemTable, "Url", "ServerUrl");
    var strID = GetAttributeFromItemTable(itemTable, "ItemId", "Id");
    //.... Other code
    strCtxHttpRootAR20111020 = ctx.HttpRoot ;
    //.... Other code
    // add a separator to the menu; warning: if the wf is modified the above guid must be updated
    CAMSep(m);
    return false;
}
 
function getCurrentItemTitleFileName(id){
    var soapEnv = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><GetListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/"><listName>CEO Documents</listName><query><Query xmlns=""><Where><Eq><FieldRef Name="ID" /><Value Type="Counter">' + id + '</Value></Eq></Where></Query></query><viewFields><ViewFields xmlns=""><FieldRef Name="Title" /><FieldRef Name="LinkFilename" /></ViewFields></viewFields></GetListItems></soap:Body></soap:Envelope>';
    $.ajax({
        url: strCtxHttpRootAR20111020 + "/_vti_bin/lists.asmx",
        type: "POST",
        dataType: "xml",
        data: soapEnv,
        complete: processResult,
        error: errorResult,
        contentType: "text/xml; charset=\"utf-8\""
    });
}        
 
function processResult(xData, status) {
    if (status == "success"){
        $(xData.responseXML).find("z\\:row").each(function() {
            var strTitle = $(this).attr("ows_Title") ;
            var strFileName = $(this).attr("ows_LinkFilename") ;
            //.... Other code
        });
    }
}    
 
function errorResult(request, status) {
    // it is executed but anyway the code then always steps into processResult , the status is "error" but this value can be readed even in processResult
}      

Note that we need to have the current http base address (for example http://srv2008moss:1010/intranet/Discovering ) but this is obtained in Custom_AddDocLibMenuItem where ctx.HttpRoot is not undefined, in the getCurrentItemTitleFileName function there is ctx but the property HttpRoot is not available, so we use a public variable (strCtxHttpRootAR20111020, note the use of a custom suffix, my initials followed from the current date) .

The soapEnv string is prone to errors when written, but there is a secure mode to obtain the correct string: before launch the query from u2U (connected by web services, not object model !) launch Fiddler , and you will have the string ready to be copied:


Advertisements
Categories: SharePoint
  1. No comments yet.
  1. 2014/09/23 at 4:33 am
Comments are closed.
%d bloggers like this: