Web Service를 이용한 파일 업로드 ( Web Service )

 

준비하기

1.     웹사이트 만들기 ( : http://local.images.co.kr )

2.     호스트 파일에 등록 : 127.0.0.1      local.images.co.kr

3.     Visual Studio -> 파일 -> 새로 만들기 -> 새 웹사이트

4.     HTTP 선택 후 http://local.images.co.kr 을 입력 후 언어는 Visual C# 선택 후 확인

5.     웹 사이트로 프로젝트 생성 완료

 

이제 웹서비스를 생성할 준비가 완료 되었다.

 

웹 서비스 만들기

1.     프로젝트에서 새 항목 추가를 클릭

2.     템플릿에서 웹 서비스 선택 후 이름은 SvcFileUpload.asmx로 생성

 

이제 웹 서비스가 완성되었다.

기본 적으로 HelloWorld() 메소드가 추가되고

이 메소드는 http://local.images.co.kr/SvcFileUpload.asmx 에서 확인 할 수 있다.

 

 

파일 업로드를 위한 웹 서비스 계획

현재 만들어진 웹 서비스가 있는 사이트를 업로드용 파일 서버로 사용할 경우로 가정한다.

1.     간단하게 아이디와 키 값을 부여

2.     아이디와 키 값이 일치 할 경우 디렉토리 생성 및 파일 업로드

3.     아이디와 키 값이 일치 할 경우 디렉토리 삭제 및 파일 삭제

 

웹 서비스에 필요한 변수

1.     아이디와 키 값 저장 변수

2.     아이디와 키 값 비교 변수

3.     저장 할 경로의 디렉토리 변수

 

웹 서비스에 필요한 메소드

1.     아이디와 키 값 비교 메소드

2.     디렉토리 생성 메소드

3.     파일 여부 체크 메소드

4.     파일 저장 메소드 새 이름으로 저장

5.     파일 저장 메소드 기존 파일 덮어 씌우기

6.     파일 삭제 메소드

 

구조는 웹사이트에서 DLL을 참조해서 웹서비스의 메소드를 호출하여 처리하는 것이다.

 

그럼 이제부터 SvcFileUpload.asmx 을 만들어 보겠다.

 

/// <summary>

/// SvcFileUpload의 요약 설명입니다.

/// </summary>

[WebService(Namespace = "http://local.images.co.kr", Name = "SvcFileUpload", Description = "파일 업로드를 처리")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

public class SvcFileUpload : System.Web.Services.WebService

{

XML Web Service를 위한 기본 네임스페이스를 설정하고 XML Web Service의 명을 정하는 것이다.

 

여러 사이트에서 하나의 업로드 서버를 사용할 수 있으므로 사이트 마다 아이디와 키를 부여하고업로드 서버 저장 경로 변수 설정

/// <summary>

/// 사이트키

/// </summary>

private Dictionary<string, string> site = new Dictionary<string, string>();

/// <summary>

/// 저장할 경로 변수

/// </summary>

private string saveDir = string.Empty;

 

/// <summary>

/// 아이디, 키값 비교 변수

/// </summary>

private bool equValue = false;

 

생성자에서 위의 변수 초기화

/// <summary>

/// 생성자

/// </summary>

public SvcFileUpload () {

 

    //디자인된 구성 요소를 사용하는 경우 다음 줄의 주석 처리를 제거합니다.

    //InitializeComponent();

 

    // 저장할 기본 경로 ( 루트 )

    saveDir = "D:\\SaveImage";

    // Key : 사이트 아이디, Value : 사이트 키 번호

    site.Add("website1", "website1111");

}

 

SvcFileUpload 웹서비스는 다음과 같이 8가지의 메소드로 구성이 된다.

1.     아이디와 키 번호 체크

2.     저장 경로 반환

3.     디렉토리 생성

4.     파일 여부 체크

5.     새로운 파일명을 생성 ( 파일명 중복 방지 )

6.     파일명이 같을 경우 같은 이름으로 저장

7.     파일명이 같을 경우 새 파일명으로 저장

8.     파일 삭제

 

아이디와 키 번호 체크 메소드

/// <summary>

/// 아이디와 키번호 체크

/// </summary>

/// <param name="id"></param>

/// <param name="kno"></param>

/// <returns></returns>

[WebMethod(Description = "아이디와 키번호 체크")]

private bool EqualsIdKno(string id, string kno)

{

    string sno = site[id];

 

    if (sno == kno)

        equValue = true;

    else

        equValue = false;

 

    return equValue;

}

 

저장 경로 반환

/// <summary>dkdle

/// 저장 경로 반환

/// </summary>

/// <returns></returns>

[WebMethod(Description = "저장 경로를 반환")]

public string ReturnDirectory()

{

    return saveDir;

}

 

디렉토리 생성

/// <summary>

/// 디렉토리를 생성

/// </summary>

/// <param name="dir"></param>

[WebMethod(Description = "디렉토리를 생성")]

public bool CreateDirectory(string dir, string id, string kno)

{

    bool createDir = false;

 

    if (EqualsIdKno(id, kno))

    {

        string strDir = string.Empty;

 

        strDir = ReturnDirectory() + "\\" + dir;

 

        //디렉토리 생성

        if (!Directory.Exists(strDir))

        {

            Directory.CreateDirectory(strDir);

        }

        createDir = true;

    }

    else

    {

        createDir = false;

    }

 

    return createDir;

}

 

파일 여부 체크

/// <summary>

/// 파일 여부 체크

/// </summary>

/// <param name="fname">저장폴더와 함께 파일명</param>

/// <returns></returns>

[WebMethod(Description = "파일 여부 체크")]

public bool EqualsFile(string fname)

{

    string strFile = ReturnDirectory() + "\\" + fname;

   

    return File.Exists(strFile);

}

 

새로운 파일명 생성

/// <summary>

/// 새로운 파일명 생성

/// </summary>

/// <param name="folderPath"></param>

/// <param name="filename"></param>

/// <returns></returns>

private string GetAvailablePathname(string folderPath, string filename)

{

    int invalidChar = 0;

    do

    {

        // 파일명에서 사용할 수 없는 문자가 들어 있는 배열을 가져온다.

        invalidChar = filename.IndexOfAny(Path.GetInvalidFileNameChars());

 

        // 사용할 수 없는 문자 제거

        if (invalidChar != -1)

            filename = filename.Remove(invalidChar, 1);

    }

    while (invalidChar != -1);

 

 

    string fullPath = Path.Combine(folderPath, filename);

    string filenameWithoutExtention = Path.GetFileNameWithoutExtension(filename);

    string extension = Path.GetExtension(filename);

 

 

 

    while (File.Exists(fullPath))

    {

        Regex rg = new Regex(@".*\((?<Num>\d*)\)");

        Match mt = rg.Match(fullPath);

 

        if (mt.Success)

        {

            string numberOfCopy = mt.Groups["Num"].Value;

            int nextNumberOfCopy = int.Parse(numberOfCopy) + 1;

            int posStart = fullPath.LastIndexOf("(" + numberOfCopy + ")");

 

            fullPath = string.Format("{0}({1}){2}", fullPath.Substring(0, posStart), nextNumberOfCopy, extension);

        }

        else

        {

            fullPath = folderPath + filenameWithoutExtention + " (2)" + extension;

        }

    }

    return fullPath;

}

웹 사이트 검색을 통해 이 부분을 다른 분이 작성한 코드를 사용했다.

이 코드의 내용은 다음의 주소에 자세히 나와 있다.

http://chaoskcuf.com/entry/C-파일명이-중복일--자동으로-이름을-생성하는-코드

 

파일명이 같을 경우 같은 이름으로 저장

/// <summary>

/// 파일을 저장 - 파일이 있을 경우 같은 이름으로 저장

/// </summary>

/// <param name="httpFile"></param>

/// <param name="dir"></param>

/// <param name="id"></param>

/// <param name="kno"></param>

/// <returns></returns>

[WebMethod(Description = "파일을 저장 - 파일이 있을 경우 같은 이름으로 저장")]

public string SameFileSaveFile(byte[] fileInfo, string dir, string fileName, string id, string kno)

{

    string checkSave = string.Empty;

    string filePath = string.Empty;

 

    // 아이디와 키 값 비교

    if (EqualsIdKno(id, kno))

    {

        // 저장할 경로

        string dirpath = ReturnDirectory() + "\\" + dir + "\\";

        filePath = dirpath + fileName;

           

        if (CreateDirectory(dir, id, kno))

        {

            try

            {

                //파일처리

                using (MemoryStream ms = new MemoryStream(fileInfo))

                {

                    using (FileStream fs = new FileStream(filePath, FileMode.Create))

                    {

                        ms.WriteTo(fs);

 

                        ms.Close();

                        fs.Close();

                    }

                }

                checkSave = fileName; // 파일명

            }

            catch

            {

                checkSave = "";

            }

        }

        else

        {

            checkSave = "";

        }

    }

    return checkSave;

}

 

파일명이 같을 경우 새 파일명으로 저장

/// <summary>

/// 파일을 저장 - 파일이 있을 경우 새이름으로

/// </summary>

/// <param name="httpFile"></param>

/// <param name="dir"></param>

/// <param name="id"></param>

/// <param name="kno"></param>

/// <returns></returns>

[WebMethod(Description = "파일을 저장 - 파일이 있을 경우 새 이름으로")]

public string NewFileSaveFile(byte[] fileInfo, string dir, string fileName, string id, string kno)

{

    string checkSave = string.Empty;

    string filePath = string.Empty;

 

    // 아이디와 키 값 비교

    if (EqualsIdKno(id, kno))

    {

        // 저장할 경로

        string dirpath = ReturnDirectory() + "\\" + dir + "\\";

 

        if (CreateDirectory(dir, id, kno))

        {

            try

            {

                // 중복되지 않는 파일명 생성

                filePath = GetAvailablePathname(dirpath, fileName);

 

                //파일처리

                using (MemoryStream ms = new MemoryStream(fileInfo))

                {

                    using (FileStream fs = new FileStream(filePath, FileMode.Create))

                    {

                        ms.WriteTo(fs);

 

                        ms.Close();

                        fs.Close();

                    }

                }

                int fnLen = filePath.Length;

                int fnStart = filePath.LastIndexOf('\\') + 1;

 

                checkSave = filePath.Substring(fnStart, fnLen - fnStart); // 파일명

            }

            catch

            {

                checkSave = "";

            }

        }

        else

        {

            checkSave = "";

        }

    }

 

    return checkSave;

}

 

파일 삭제

/// <summary>

/// 파일을 삭제한다.

/// </summary>

/// <param name="DirPath">디렉토리 절대경로</param>

/// <param name="FileName">파일명</param>

/// <returns></returns>

[WebMethod(Description = "파일을 삭제한다.")]

public bool DeleteFile(string dir, string filename, string id, string kno)

{

    bool checkDel = false;

   

    // 아이디와 키 값 비교

    if (EqualsIdKno(id, kno))

    {

        try

        {

            string strDir = string.Empty;

 

            strDir = ReturnDirectory() + "\\" + dir + "\\";

 

            //파일삭제

            if (File.Exists(strDir + filename))

            {

                File.Delete(strDir + filename);

            }

            checkDel = true;

        }

        catch

        {

            checkDel = false;

        }

    }

    else

        checkDel = false;

 

    return checkDel;

}

 

위의 소스에서 아이디와 키값이 일치 하지 않으면 디렉토리 생성이나 파일 업로드 그리도 삭제 모두 되지 않는 것을 볼 수 있다.

 

이와 같이 파일 업로드에 필요한 대부분의 메소드를 생성했다.

 

다음 장에서는 DLL 만들어 웹 서비스 자원을 어떻게 사용하는지를 알아보겠다.


If you read this blog you probably know that besides the web user interface, SharePoint also exposes some interfaces which you can use from code: the SharePoint object model and the SharePoint web services. The object model of SharePoint can only be used by code/applications that are running on a SharePoint server in your Server Farm, so you can’t use the object model on client machines. The SharePoint web services can be used of course across a network boundary, that’s what they are built for! In this post I’m going to show you how you can access the out-of-the-box SharePoint web services by making use of the jQuery Javascript library. First let’s see what you can do with this technique: download this zip file that contains an ASPX page (a basic Site Page without any code behind), and the jQuery Javascript library (in case you don’t have it already). Upload the two individual files (not the zip file) in the root of a Document Library in any of your SharePoint sites. You can do this by making use of the web user interface; you don’t have to touch anything on the server itself. When done, just click on the link of the uploaded ASPX and you’ll see following page:


 
Probably you’re not really impressed but think about the fact that this page is just an ASPX file you’ve uploaded through the web user interface, there is absolutely no code behind involved (which would have been blocked by SharePoint’s default security settings). The details of the SharePoint lists are loaded by making use of Javascript code that calls the web SharePoint lists.asmx web service.

So how do you call a SharePoint web service in Javascript code; well you can use the XmlHttpRequest object and write lots of boring code, or you can make use of a Javascript library that wraps this XmlHttpRequest object and exposes a nice and easy interface. In this demo I’ll use the jQuery Javascript library, so the first thing that you’ll need to do is to make sure the page is loading that library:

<script type="text/javascript" src="jquery-1.3.2.min.js" mce_src="jquery-1.3.2.min.js"></script>

If you already configured your SharePoint site so the jQuery library is loaded (for example by making use of the SmartTools.jQuery component), you can skip this line of course. 

When the page is loaded, the Lists web service (e.g. http://yoursite/_vti_bin/lists.asmx) of SharePoint needs to be called; this can be accomplished by making use of the jQuery’s ajax method. This method can post the necessary SOAP envelope message to the Lists web service. The XML of the SOAP envelope can easily be copied from the .NET web service test form of the desired web method (e.g. http://yoursite/_vti_bin/lists.asmx?op=GetListCollection). In the code below, a call to the GetListCollection web method is made when the page is loaded. The complete parameter of the ajax method is actually a pointer to another Javascript function (which we’ll implement later on) that will be called asynchronously when the web service call is done.  Don’t forget to update the url parameter with your SharePoint site’s URL!

$(document).ready(function() {
    var soapEnv =
        "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'> \
            <soapenv:Body> \
                <GetListCollection xmlns='http://schemas.microsoft.com/sharepoint/soap/'> \
                </GetListCollection> \
            </soapenv:Body> \
        </soapenv:Envelope>";

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

As I already mentioned, the processResult function is called when the response XML of the web service call is received. In this method a loop is created which will iterate over every List element of the response XML. For every List element a <li></li> element is added to the element with the ID attribute set to data.

function processResult(xData, status) {
    $(xData.responseXML).find("List").each(function() {
        $("#data").append("<li>" + $(this).attr("Title") + "</li>");
    });
}

This data element is the actual <ul></ul> list in HTML:

<ul id="data"></ul>

When you put everything together in a Site Page, this is the result:


 
In the zip file mentioned in the beginning of this post, you can find an extended version of the processResult function which will display some additional metadata for every list (like the ID, ItemCount etc). The entire contents of basic version of the Site Page built in this post goes as follows:

<%@ Page Language="C#" MasterPageFile="~masterurl/default.master" %>

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

    <script type="text/javascript" src="jquery-1.3.2.min.js" mce_src="jquery-1.3.2.min.js"></script>

    <script type="text/javascript">
        $(document).ready(function() {
            var soapEnv =
                "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'> \
                    <soapenv:Body> \
                        <GetListCollection xmlns='http://schemas.microsoft.com/sharepoint/soap/'> \
                        </GetListCollection> \
                    </soapenv:Body> \
                </soapenv:Envelope>";

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

        });

        function processResult(xData, status) {
            $(xData.responseXML).find("List").each(function() {
                $("#data").append("<li>" + $(this).attr("Title") + "</li>");
            });
        }
    </script>

</asp:Content>
<asp:Content runat="server" ContentPlaceHolderID="PlaceHolderMain">
    <ul id="data"></ul>
</asp:Content>
<asp:Content runat="server" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea">
    List Details
</asp:Content>
<asp:Content runat="server" ContentPlaceHolderID="PlaceHolderPageTitle">
    List Details
</asp:Content>

[C# 코드]

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

[WebService(Namespace =
"http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
public Service () {

//Uncomment the following line if using designed components
//InitializeComponent();
}

[WebMethod]
public string HelloWorld(string strName) {
return "Hello" +strName;
}

}


[Html 코드]

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title>Untitled Page</title>

 <script type="text/javascript">

function sendDataAsXML_SOAP() {

var req_params = "", url = "", number = 0, type = "";

/* Configure Parameters */

url = "http://localhost/TestWebservice/Service.asmx";

user = document.getElementById("Text1").value;

 req_params = "<?xml version=\"1.0\" encoding=\"utf-8\"?><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 >";

req_params = req_params + "<strName>" + user + "</strName>";

req_params = req_params + "</HelloWorld></soap:Body></soap:Envelope>";

alert(req_params);

/* Send XML/SOAP Request To Web Service Using Browser's Javascript DOM */

try {

ajax_request = new XMLHttpRequest();

}

catch (trymicrosoft) {

try {

ajax_request = new ActiveXObject("Msxml2.XMLHTTP");

}

catch (othermicrosoft) {

try {

ajax_request = new ActiveXObject("Microsoft.XMLHTTP");

}

catch (failed) {

ajax_request = false;

}

}

}

ajax_request.open("POST", url, true);

ajax_request.setRequestHeader("Content-Type", "text/xml;charset=utf-8");

ajax_request.onreadystatechange = receiveXML_SOAPData;

ajax_request.send(req_params);

}

function receiveXML_SOAPData() {

if (ajax_request.readyState == 4) {

if (ajax_request.status == 200) {

/* Parse The Response Data */

//result.innerText = ajax_request.responseText;

alert(ajax_request.responseText);

}

}

}

</script>

</head>

<body>

<form action="#">

<input type="text" id="Text1" />

<input type="button" onclick="sendDataAsXML_SOAP();" value="Call WebService" />

</form>

</body>

</html>

You can add a web reference to each SharePoint web service through your Visual Studio .NET IDE. In your Solution Explorer right click on your project and select "Add Web Reference" from your popup menu. The table below shows the URLs to use for each web service provided by WSS. Enter the URL to the web service and click the Go button. This will show you in the dialog box a summary of all available web methods. Next enter the name of the web reference and then click Add Reference.

WSS Web Services

Web Reference

Administration Service

http:///_vti_adm/admin.asmx

Alerts Service

http:///_vti_bin/alerts.asmx>

Document Workspace Service

http:///_vti_bin/dws.asmx>

Forms Service

http:///_vti_bin/forms.asmx>

Imaging Service

http:///_vti_bin/imaging.asmx>

List Data Retrieval Service

http:// /_vti_bin/dspsts.asmx>

Lists Service

 http:///_ vti_bin/lists.asmx>

Meetings Service

http:/// _vti_bin/meetings.asmx>

Permissions Service

http:// /_vti_bin/permissions.asmx>

Site Data Service

http:///_vti_bin/sitedata.asmx>

Site Service

http:///_vti_bin/sites.asmx>

Users and Groups Service

http:///_vti_bin/usergroup.asmx>

Versions Service

http:///_vti_bin/versions.asmx>

Views Service

http:///_vti_bin/views.asmx>

Web Part Pages Service

http:// /_vti_bin/webpartpages.asmx>

Webs Service

http:///_vti_bin/webs.asmx>

Setting the web service user credentials

The SharePoint web services only accept calls from existing SharePoint users and do also enforce access security. Import the System.Net namespace into your project and then use the NetworkCredential class to set the user credential to use for the web service call. Here is a code snippet:

public
static XmlNode VersionsGetVersions(string SharePointHost, string UserName, string Password, string Domain, string FileName)
{
// proxy object to call the Versions web service
Versions.Versions VersionsService = new Versions.Versions();
// the user credentials to use
VersionsService.Credentials = new NetworkCredential(UserName, Password, Domain);
VersionsService.Url = SharePointHost + "_vti_bin/Versions.asmx";
// gets the file versions
XmlNode Result = VersionsService.GetVersions(FileName);
// dispose the web service object
VersionsService.Dispose();
return Result;
}

For example, first you create an instance of the Versions web service. Then you assign a new instance of the NetworkCredential class to the Credentials property on the created web service object. We pass along the user name, password and the user's domain name to the NetworkCredential object. Next you set the web service URL, which might very well be different from the one used when you created the web reference. Finally you invoke the desired web method, in the code snippet above the GetVersions() web method. The web method takes a file name and returns a XML document with all available versions of this file (Document libraries can have versioning enabled and then keep a history for each version). At the end you call Dispose() on the web service object to free up any underlying unmanaged resources.

If the user does not exist in SharePoint or does not have the permission to perform the operation then a WebException is thrown by SharePoint. The returned HTTP status is 401, which means unauthorized request. There are some inconsistencies across all web services. For example some web methods take a XML string as input while others take an XmlNode as input. Most web methods return the result as XmlNode while others return a XML string and while others again return complex data structures. But after you get used to these inconsistencies it is very easy to use these web services and integrate SharePoint capabilities right into your application.

A summary of the "Windows SharePoint Services" web services

The following table provides an overview what capabilities are exposed through the "Windows SharePoint Services" web services. Each web service is targeted towards a specific area although there is some overlap. You for example can use the Lists web service and the Site Data web service to work with SharePoint lists, or you can use the Site Data web service and the Webs web service to work with sites meta-data and sub-sites. Please refer to the attached "SharePoint web service browser" sample application which provides a windows form interface to browse all web services and all its web methods. It enables you to play with each web method or web service and better understand its usage. It also displays to each web service and web method the detailed SDK help page.

WSS Web Services

Description

Administration Service

This web service provides administrative capabilities like creating a new top-level site, deleting a top-level site and getting the list of available languages.

Alerts Service

Provides access to the list of active alerts and allows to delete active alerts.

Document Workspace Service

This web service is used to manage Document Workspace sites. It allows to create new document workspaces, delete document workspaces, create new sub-folders, delete sub-folders, etc.

Forms Service

Each list has forms associated which are used to display list items, create new list items and update or delete existing list items. This web service allows to get the collection of forms associated with a list and then get detailed information about each form.

Imaging Service

SharePoint has picture libraries which users can use to manage pictures. This web service allows to upload pictures, download pictures, create new folders, delete folders and pictures, etc.

List Data Retrieval Service

Allows to run XPath like queries against a list.

Lists Service

This web service is used to work with lists and list data. You can obtain the collection of lists, add new lists, remove lists, add new list attachments, remove attachments, etc.

Meetings Service

This web service is used to work with Meeting Workspaces. You can create a new Meeting workspace, remove an existing Meeting workspace, add new meetings, add new meetings using ICal files, etc.

Permissions Service

Sites and lists have permissions assigned to them. This web service is used to obtain the permissions assigned to a list or site, add new permissions and update or removing existing permissions.

Site Data Service

The Site Data web service can be used to return meta-data about a site or list, get the collection of lists, get the attachments for a list item, get the collection of items in a list, etc.

Site Service

This web service can be used to return the list of site templates. When you create a new site using the Administration web service you need to specify the site template name to use which you can obtain through this web service.

Users and Groups Service

This web service is used to work with users, site-groups and cross-site groups. You can add, update or remove users, site-groups and cross-site groups. You can also add users or cross-site-groups to a site-group.

Versions Service

Document Libraries and Picture Libraries can have versioning enabled, which stores a copy of every single file version. This web service can be used to get the list of available versions, delete versions and also restore a file version.

Views Service

Lists have views associated which define what fields are shown, what filtering and sorting is applied, what grouping is applied, etc. This web service is used to work with list views. You can get the collection of views, add new views, remove views, update the Html code used to display a view, etc.

Web Part Pages Service

Web Parts are objects which you can place on web part pages. This web service is used to work with web parts and web part pages. You can get the list of web parts on a page, you can add or remove web parts, etc.

Webs Service

This web service is used to work with sites and sub-sites. You can get the list of list-templates, get meta-data about a sub-site, get the list of sub-sites, etc.

A summary of the SharePoint Portal Server web services

SharePoint Portal Server provides the same web services as Windows SharePoint Services. It also provides the following five additional web services.

WSS Web Services

Description

Area Service

Areas are sections used in SharePoint Portal Server to group content. This web service allows to manage areas. You can create new areas, update areas, remove areas, get the list of sub-areas, etc.

Query Service

The Query web service is used by clients to search SharePoint. You can send in complex search XML requests and get a result-set of matches.

User Profile Service

Users in SPS have user profiles that are used to target content to audiences (users). This web service allows to obtain user profile information. It does not allow to create or modify user profiles.

SPS Crawl Service

This web service is undocumented and is used by SharePoint itself for site crawling purposes.

Outlook Adapter Service

Provides the same capabilities as the Alerts web service of WSS.

   

The table below shows the URLs to use for each web service provided by SharePoint Portal Server. You can add them the same way as the WSS web services described above.

WSS Web Services

Web Reference

Area Service

http:///_vti_bin/areaservice.asmx>

Query Service

http:///_vti_bin/search.asmx>

User Profile Service

http:// /_vti_bin/userprofileservice.asmx

SPS Crawl Service

http:///_vti_bin/spscrawl.asmx>

Outlook Adapter Service

http:// /_vti_bin/outlookadapter.asmxd>

Namespaces used in the returned SharePoint XML documents

Many of the web methods return its result in form of an XML document. Most root nodes have a namespace URI associated with it. Here is an example XML document returned by the GetListCollection() web method (on the Lists web service). Please note that this is just a partial XML snippet for demonstration purpose:

Naturally we would think of running an XPath query like "//List" using the SelectNodes() method on the XmlDocument or XmlNode object. We expect it to return all the List nodes of this XML document. But the result returned is empty. The reason being that you need to query within the namespace associated with the root node. But how do you do that if there is no namespace qualifier (or prefix) associated with the namespace URI. We need to use the XmlNamespaceManager class to associate a namespace prefix to the namespace URI. Here is the code snippet:

private XmlNodeList RunXPathQuery(XmlNode XmlNodeToQuery, string XPathQuery) {
// load the complete XML node and all its child nodes into a XML document XmlDocument Document = new XmlDocument();
Document.LoadXml(XmlNodeToQuery.OuterXml);
// all the possible namespaces used by SharePoint and a randomly choosen prefix
const
string SharePointNamespacePrefix = "sp";
const string SharePointNamespaceURI = http://schemas.microsoft.com/sharepoint/soap/";
const string ListItemsNamespacePrefix = "z";
const string ListItemsNamespaceURI = "#RowsetSchema";
const string PictureLibrariesNamespacePrefix = "y";
const string PictureLibrariesNamespaceURI = http://schemas.microsoft.com/sharepoint/soap/ois/";
const string WebPartsNamespacePrefix = "w";
const string WebPartsNamespaceURI = http://schemas.microsoft.com/WebPart/v2;
const string DirectoryNamespacePrefix = "d";
const string DirectoryNamespaceURI = http://schemas.microsoft.com/sharepoint/soap/directory/;
// now associate with the xmlns namespaces (part of all XML nodes returned
// from SharePoint) a namespace prefix which we can then use in the queries

XmlNamespaceManager NamespaceMngr = new XmlNamespaceManager(Document.NameTable); NamespaceMngr.AddNamespace(SharePointNamespacePrefix, SharePointNamespaceURI); NamespaceMngr.AddNamespace(ListItemsNamespacePrefix, ListItemsNamespaceURI); NamespaceMngr.AddNamespace(PictureLibrariesNamespacePrefix, PictureLibrariesNamespaceURI); NamespaceMngr.AddNamespace(WebPartsNamespacePrefix, WebPartsNamespaceURI); NamespaceMngr.AddNamespace(DirectoryNamespacePrefix, DirectoryNamespaceURI);
// run the XPath query and return the result nodes
return Document.SelectNodes(XPathQuery, NamespaceMngr);
}

First we create a new XmlDocument object and load the XML string of the passed along XmlNode into it. This way we can manipulate the XML document as needed without affecting the original XmlNode object itself. Then we create an XmlNamespaceManger object and assign it to the XmlDocument object. This we do by passing along the NameTable property of the XmlDocument. Next we add all the namespace URI's with its namespace prefixes. There are five different namespaces you will run into frequently (see declared constants). Finally we run the XPath query and return the collection of matching XML nodes. The namespace shown in our sample XML snippet gets the "sp" namespace prefix associated so our XPath query would change to "//sp:List". This will now return all matching XML nodes.

Some real life examples of using the SharePoint web services

The following examples demonstrate how you can leverage the SharePoint web services to interact tightly with SharePoint from within your application. The detailed code for each example can be found in the attached "SharePoint explorer" sample application. The description below explains which web service and web method to use to obtain the desired SharePoint information.

Example 1 - Get the collection of SharePoint lists, fields and views

In the first example we want to get the collection of SharePoint lists. For each list we want to get all the defined list fields (fields you can use to store information) and finally all views associated with the list. Here are the web methods to call:

  • On the Lists web service call the GetListCollection() web method to get the collection of all SharePoint lists. This returns an XML document with all SharePoint lists.
  • Next you run the "//sp:List" XPath query to get all matching List nodes. The Title attribute of each matching node contains the name of the SharePoint list.
  • For each SharePoint list we call the GetList() web method on the Lists web service, passing along the list name. This returns a XML document with detailed information about the list including the list of fields.
  • Next you run the "//sp:Field" XPath query to get all the matching Field nodes. The Name attribute contains the field name.
  • For each SharePoint list we call the GetViewCollction() web method on the Views web service, passing along again the list name. This returns a XML document listing all views for the list.
  • Finally you run the "//sp:View" XPath query to get all the matching View nodes. The Name attribute contains the name of the view.

Example 2 - Get the list of users and site-groups

In this example we want to get the list of site users and to which site group each user belongs. We also want to get the list of site groups and which users belong to each site group.

  • On the Users-and-Groups web service we call the GetUserCollectionFromWeb() web method. This returns an XML document with all the site users.
  • Next you run the "//d:User" XPath query to get all the matching User nodes. The Name attribute contains the user name and the LoginName attribute the user's login name.
  • For each user we call the GetRoleCollectionFromUser() web method on the Users-and-Groups web service passing along the user's login name. This returns a XML document with all the site groups the user belongs to.
  • Next you run the "//d:Role" XPath query to get all the matching Role nodes. The Name attribute contains the site group name.
  • To get the list of site groups call the GetRoleCollectionFromWeb() web method on the Users-and-Groups web service. This returns an XML document with all site groups.
  • Next you run again the "//d:Role" XPath query to get all the matching Role nodes. The Name attribute contains the site group name.
  • Finally call for each site group the GetUserCollectionFromRole() web method on the Users-and-Groups web service passing along the site group name. This returns an XML document with all the users belonging to this site group.
  • Next you run again the "//d:User" XPath query to get all the matching User nodes. The Name attribute contains the user name and the LoginName attribute the user's login name.

Example 3 - Get the list of sites, site-templates and list-templates

With the last example we want to get a list of all sites in the site collection. We want to get for the site collection the list of site templates. Additionally we want for each site the list of list templates.

  • First we call the GetAllSubWebCollection() web method on the Webs web service. This returns an XML document with all sites in the site collection.
  • Next run the "//sp:Web" XPath query to return all matching Web nodes. The Url attribute contains the absolute URL for the site.
  • Then we call the GetSiteTemplates() web method on the Sites web service. This returns an array of available site templates in the site collection, which is an array of the type Sites.Templates. The attached sample application converts all structures to an XML document using reflection, so you can run XPath queries against it (see the method SharePoint.SitesGetSiteTemplates()).
  • Next run the "//SharePointServices.Sites.Templates" XPath query which returns all matching template nodes. The Title attribute contains the template title and the Name attribute the SharePoint template name.
  • For each site we call the GetListTemplates() web method on the Webs web service. Before calling the web service object you need to set the URL to the site URL (returned by GetAllSubWebCollection()). This way we make sure that t he call is to the site itself and returns the list templates of that site. This returns an XML document with all list templates.
  • To finish run the "//sp:SiteTemplate" XPath query to return all matching SiteTemplate nodes. The DisplayName attribute contains the name of the list template.

Summary

SharePoint comes with a vast number of web services and web methods which enable you to tightly integrate SharePoint capabilities into your application. It is very easy to learn and use these web services and web methods. Please refer to the attached "SharePoint web service browser" example which provides a complete wrapper class for all existing (about 150) web methods. This removes the burden of adding all the web references and worrying about the details how to instantiate each web method, etc. The sample application provides a user interface to explore all web methods. You can browse the web services and web methods, display the SDK help page, enter the input values, execute the web method and look at the displayed output values.

The second example - "SharePoint explorer" provides a much more comprehensive sample of how to use and work with the SharePoint web services and web methods. It retrieves as much information and displays the data in lists and tree nodes (always running simple XPath queries against the result-set). The user interface allows you to traverse through the related data. You can also write your own web services using the managed SharePoint server API. Here is a sample application which provides a document check-in and check-out capability through a new web service.

+ Recent posts