Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I know your problem. Microsoft has really bad examples on MSDN. Lot of stuff doesn't work or has just been copied from the 2007 manual. I've started yesterday to develop with the Webservice for Project Server 2010.</p> <p>Here is a simple (maybe not the best) solution for setting custom fields:</p> <p><strong>Complete source code: <a href="http://pastebin.com/tr7CGJsW" rel="nofollow noreferrer">http://pastebin.com/tr7CGJsW</a></strong></p> <h2>Prepare your solution</h2> <p>First I've added a Service Reference to:</p> <blockquote> <p>http: //servername/instance/_vti_bin/PSI/Project.asmx?wsdl</p> </blockquote> <p><a href="https://i.stack.imgur.com/q0S9S.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/q0S9S.png" alt="Service Reference"></a></p> <p>After that, I've edited the app.config because I had to use special credentials to login into the project server (<strong>maybe this is not necessarily for you</strong>):</p> <pre class="lang-xml prettyprint-override"><code>... &lt;security mode="TransportCredentialOnly"&gt; &lt;transport clientCredentialType="Ntlm" proxyCredentialType="Ntlm" realm="" /&gt; &lt;message clientCredentialType="UserName" algorithmSuite="Default" /&gt; &lt;/security&gt; &lt;!--&lt;security mode="None"&gt; &lt;transport clientCredentialType="None" proxyCredentialType="None" realm="" /&gt; &lt;message clientCredentialType="UserName" algorithmSuite="Default" /&gt; &lt;/security&gt;--&gt; &lt;/binding&gt; </code></pre> <p><em>The commented code has been created by Visual Studio</em></p> <h2>Connect and Update</h2> <p>Now we can create a new SoapClient which communicates with the Project Server:</p> <pre class="lang-cs prettyprint-override"><code>//Creating a new service client object ProjectSoapClient projectSvc = new ProjectSoapClient(); //Just if you need to authenticate with another account! projectSvc.ClientCredentials.Windows.ClientCredential = new NetworkCredential("test", "test", "demo"); projectSvc.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation; </code></pre> <p>Now I have declared two Guids, that we know, what we want to update. The other variables are used later and are comment in the code:</p> <pre class="lang-cs prettyprint-override"><code>//Guid of my project Guid myProjectId = new Guid("{610c820f-dc74-476c-b797-1e61a77ed6c6}"); //Guid of the custom field Guid myCustomFieldId = new Guid("{cd879634-b3ee-44eb-87f7-3063a3523f45}"); //creating a new sessionId and a new jobId Guid sessionId = Guid.NewGuid(); //the sessionId stays for the whole updating process Guid jobId = Guid.NewGuid(); //for each job, you give to the server, you need a new one //indicator if you have to update the project Boolean updatedata = false; </code></pre> <p>Then we are ready to load the <a href="https://msdn.microsoft.com/en-us/library/gg224487.aspx" rel="nofollow noreferrer">ProjectDataSet</a> from the server, find the CustomField and updating the data. It's really simple:</p> <ol> <li>loading the ProjectDataSet</li> <li>iterate trough the CustomFieldsRow</li> <li>checking if the CustomField matches with our Guid</li> <li>updating the value</li> <li>setting the indicator to update</li> </ol> <pre class="lang-cs prettyprint-override"><code>//loading project data from server //Every change on this dataset will be updated on the server! ProjectDataSet project = projectSvc.ReadProject(myProjectId, DataStoreEnum.WorkingStore); //To find your custom field, you have to search for it in the CustomFieldsRow foreach (ProjectServerCSVImport.PSS.Project.ProjectDataSet.ProjectCustomFieldsRow row in project.ProjectCustomFields) { //check if the GUID is the same if (row.MD_PROP_UID == myCustomFieldId) { //if yes, write it into the container row.NUM_VALUE = 12345; //and set the indicater updatedata = true; } } </code></pre> <p>If we changed a value, we have to send the ProjectDataSet to the ProjectServer now. It will update the changed values in the ProjectDataSet. For this, we have to check out our project, update it and check in again:</p> <pre class="lang-cs prettyprint-override"><code>//update if you have changed anything if (updatedata) { //check out the project first projectSvc.CheckOutProject(myProjectId, sessionId, "custom field update checkout"); //send the dataset to the server to update the database bool validateOnly = false; projectSvc.QueueUpdateProject(jobId, sessionId, project, validateOnly); //wait 4 seconds just to be sure the job has been done System.Threading.Thread.Sleep(4000); //create a new jobId to check in the project jobId = Guid.NewGuid(); //CheckIn bool force = false; string sessionDescription = "updated custom fields"; projectSvc.QueueCheckInProject(jobId, myProjectId, force, sessionId, sessionDescription); //wait again 4 seconds System.Threading.Thread.Sleep(4000); </code></pre> <p>But now we just have updated the database. The server will still show us the "old" value and not the new one. This is because we didn't have published our project yet:</p> <pre class="lang-cs prettyprint-override"><code>//again a new jobId to publish the project jobId = Guid.NewGuid(); bool fullPublish = true; projectSvc.QueuePublish(jobId, myProjectId, fullPublish, null); //maybe we should wait again ;) System.Threading.Thread.Sleep(4000); </code></pre> <p>Finally we're done and our project is updated!</p> <h2>Enhancements</h2> <p>I'm very new to this platform (Project Server 2010), so this code maybe is not the best example. So there are some enhancements, which would made the solution better:</p> <ul> <li>The Sleep function is a very bad workaround, but I couldn't find an example which handles the same thing (<a href="http://msdn.microsoft.com/en-us/library/websvcproject.project.readproject%28v=office.12%29.aspx" rel="nofollow noreferrer">like here</a>) with a <a href="https://msdn.microsoft.com/en-us/library/websvcqueuesystem.queuesystem(v=office.12).aspx" rel="nofollow noreferrer">QueueSystem</a> for 2010?!</li> <li>If you don't know the Guid of your project, but the name, you can resolve it by following function:</li> </ul> <pre class="lang-cs prettyprint-override"><code>/// &lt;summary&gt; /// Returns the GUID for a specified project /// and sets the guid for this class /// &lt;/summary&gt; /// &lt;param name="client"&gt;soap service client&lt;/param&gt; /// &lt;param name="projectname"&gt;name of the project&lt;/param&gt; /// &lt;returns&gt;Project GUID&lt;/returns&gt; public Guid GetGuidByProjectName(ProjectSoapClient client, string projectname) { Guid pguid = new Guid(); ProjectDataSet data = client.ReadProjectList(); foreach (DataRow row in data.Tables[0].Rows) { if (row[1].ToString() == projectname) //compare - case sensitive! { pguid = new Guid(row[0].ToString()); } } return pguid; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload