共用方式為


PS2007 Project Details (JavaScript)

Post three and now things are getting a little more interesting. We leave the blanket of .Net and head out into the cold harsh reality of HTML, XML, and JavaScript. I want to do the same thing I did in the previous examples... get the list of projects on the Project Server, then display the details of each one on demand. First thing I need to do is figure out how to call a web service from JavaScript. First thought is SOAP toolkit, I used to use that back in the day. But it has been deprecated due to .Net, that's a no starter. How about XMLHTTP? It comes with XML so it should be installed on many user machines already, I think this is the way to go. After some research I find a good structure for using XMLHHTP is

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

    xmlhttp.open("POST", sSoapPostURL, false);

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

    xmlhttp.setRequestHeader("SOAPAction", sSoapAction);

    xmlhttp.send(sRequest);

We’ve go three parameters to deal with: sSoapPostURL, sSoapAction, sRequest

sSoapPostURL is pretty straight forward, it’s the URL for the web service. I’ve done this from .Net, it should look something like:

sSoapPostURL = myserver + '/_vti_bin/psi/project.asmx';

sSoapAction starts me scratching my head. It hasn’t been that long since I’ve written to a web service without .Net… has it? Yeah it has, been then I remember the WSDL (Web Service Description Language). Every web service needs one of these and that is where I get the information from. I start hunting through the Project Server directories, and don’t find a WSDL file in sight. What I do find is a bunch of aspx files named like projectwsdl.aspx and projectdisco.aspx. I open them up and surprise, just what I’m looking for. I have the signature of the service and can go dancing in the 70s after (ok bad joke). But….aaaackkk what a mess to navigate. Just when I’m about to dig in I remember adding web services to .Net… and a cool dialog box that has everything I’m looking for. I go to the “Add Web Reference” dialog, and reference project.asmx. I get a list of methods, click on ProjectList and sweet nectar I see the following:

POST /SharedServices1/PSI/project.asmx HTTP/1.1

Host: lduffps2007

Content-Type: text/xml; charset=utf-8

Content-Length: length

SOAPAction: "https://schemas.microsoft.com/office/project/server/webservices/Project/ReadProjectList"

<?xml version="1.0" encoding="utf-8"?>

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

  <soap:Body>

    <ReadProjectList xmlns="https://schemas.microsoft.com/office/project/server/webservices/Project/" />

  </soap:Body>

</soap:Envelope>

Not only have I found my SoapAction, but exactly what I need for the Request too. It even told me I’d get back a dataset, which I kind-of already figured since everything is a dataset in the PSI.

HTTP/1.1 200 OK

Content-Type: text/xml; charset=utf-8

Content-Length: length

<?xml version="1.0" encoding="utf-8"?>

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

  <soap:Body>

    <ReadProjectListResponse xmlns="https://schemas.microsoft.com/office/project/server/webservices/Project/">

      <ReadProjectListResult>dataset</ReadProjectListResult>

    </ReadProjectListResponse>

  </soap:Body>

</soap:Envelope>

OK we have a way to call the Project web service, using XMLHTTP. We have the parameters to pass in courtesy of .Net Add Web Reference dialog. I pull it together, make a call to get my list of projects and realize… what do I do with a dataset when I’m not in .Net? In my previous example I made EXTENSIVE use of binding datasets to UI elements, that’s not going to fly here. Wait, the serialized version of a dataset is just XML. I’m already hammering XML via XMLHTTP, how about a little DOM action? Off we go to load the DOM with the dataset that got returned. I start “spelunking” the DOM in search of my data, where the &^($^! is my data. I finally push the XML out to a file, then reload it in a DOM in .Net. Then I debug the DOM and find the data six levels deep, WOW! So to get the project list I end up with the following:

 projects = xmlObj.childNodes(0).childNodes(0).childNodes(0).childNodes(1).childNodes(0).childNodes;

Once I find that it’s a matter of jamming this into some UI elements. Then I want to display the details of the project, so I retrace my steps for ReadProject. Once you get though the questions of how to talk to the web service and how to consume the data coming back it’s pretty straight forward.

A big word of WARNING!!! I did this sample on beta 2… it crashed and burned on beta 2 technical refresh. It took me a couple weeks off and on to figure out the problem… the namespaces had been completely changed. Even though the calls hadn’t really changed, the namespace change crashed the sample around my ears. And we all know how fun it is to debug JavaScript (alert(sRequest); … ) ALL the information in the SOAP headers is very important, not just the signature of the method call.

Attached is the complete sample for your enjoyment. Don’t forget to change yourserver/pwa to reflect your instance.

 

ProjectDetailsHTML.zip

Comments

  • Anonymous
    December 14, 2006
    This is fantastic - thanks Larry.

  • Anonymous
    January 30, 2007
    if u give the webservices for sample.it will be usefull. pramod

  • Anonymous
    March 05, 2007
    The comment has been removed

  • Anonymous
    March 14, 2007
    Hi Larry, This is great for getting a project dataset.....what if you want to send a project dataset?  I'm trying to use QueueCreateProject through soap and even though I get a successful response back, I don't see any new projects created, nor do I find anything in the queue history.  What is the correct format for sending a project dataset through soap? I've tried creating the project dataset in .net and then serializing it to xml, and then sending an XMLDOM activex object, and I've tried sending it in plain text, and sending it in plain text with cdata around it.  Some fail, some say they were successful, but I never get any new projects actually created. Any thoughts on this??

  • Anonymous
    April 04, 2007
    Thank you very much Larry... Fantastic tutorial, I got my code working after reading your artical.. and understood SOAP better. Thank you..

  • Anonymous
    April 19, 2007
    hello that not work for me i have an errour here pls any help

  • Anonymous
    April 19, 2007
    hi dose not work for me where is the errour thx

  • Anonymous
    April 19, 2007
    i have problem with xmlhttp.open("POST", sSoapPostURL, false);

  • Anonymous
    April 19, 2007
    you say "It comes with XML so it should be installed on many user machines already, I think this is the way to go" what it should be installed?

  • Anonymous
    December 12, 2007
    pls provide with some examples