使用PSI设置自定义字段-Microsoft Project Server [英] Setting custom fields using the PSI - Microsoft Project Server

查看:149
本文介绍了使用PSI设置自定义字段-Microsoft Project Server的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Project Server开发的新手,想知道是否可以使用PSI设置资源自定义字段值。



我似乎找不到任何内容



我目前已经为CustomFields和Resource Web服务设置了Web引用,但是不确定如何为特定字段设置自定义字段。



任何帮助将不胜感激!



谢谢!

解决方案

我知道您的问题。微软在MSDN上确实有不好的例子。很多东西不起作用,或者只是从2007年手册中复制而来。我昨天开始使用Project Server 2010的Web服务进行开发。



这里是设置自定义字段的简单(也许不是最好的)解决方案:



完整的源代码:



在那之后,我编辑了app.config,因为必须使用特殊凭据登录项目服务器(也许不一定适合您):

  ... 
< security mode = Transpor tCredentialOnly>
< transport clientCredentialType = Ntlm proxyCredentialType = Ntlm realm = />
< message clientCredentialType = UserName algorithmSuite = Default />
< / security>
<!-<安全模式=无>
< transport clientCredentialType = None proxyCredentialType = None
realm = />
< message clientCredentialType = UserName algorithmSuite = Default />
< / security>->
< / binding>

注释的代码已由Visual Studio创建



连接和更新



现在我们可以创建一个新的SoapClient来与Project Server通信:

  //创建新的服务客户端对象
ProjectSoapClient projectSvc = new ProjectSoapClient();

//如果您需要通过另一个帐户进行身份验证!
projectSvc.ClientCredentials.Windows.ClientCredential = new NetworkCredential( test, test, demo);
projectSvc.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

现在,我声明了两个Guid,我们知道要更新的内容。其他变量稍后使用并在代码中进行注释:

  //我的项目的指导
Guid myProjectId = new Guid( {610c820f-dc74-476c-b797-1e61a77ed6c6});

//自定义字段
的向导Guid myCustomFieldId = new Guid( {cd879634-b3ee-44eb-87f7-3063a3523f45});

//创建一个新的sessionId和一个新的jobId
Guid sessionId = Guid.NewGuid(); // sessionId在整个更新过程中保持不变
Guid jobId = Guid.NewGuid(); //对于每个作业,您将其交给服务器,则需要一个新的

//如果必须更新项目
,则必须使用该指示器Boolean updatedata = false;

然后我们准备加载 ProjectDataSet 从服务器中找到CustomField并更新数据。这真的很简单:


  1. 加载ProjectDataSet

  2. 通过CustomFieldsRow迭代

  3. 检查CustomField是否与我们的Guid匹配

  4. 更新值

  5. 将指标设置为更新



  //从服务器
加载项目数据//此数据集的每次更改将在服务器上更新!
ProjectDataSet project = projectSvc.ReadProject(myProjectId,DataStoreEnum.WorkingStore);

//要找到您的自定义字段,必须在CustomFieldsRow
foreach中搜索它(project.ProjectCustomFields中的ProjectServerCSVImport.PSS.Project.ProjectDataSet.ProjectCustomFieldsRow行)
{
//检查GUID是否相同
if(row.MD_PROP_UID == myCustomFieldId)
{
//如果是,请将其写入容器
row.NUM_VALUE = 12345;

//并设置指示符
updatedata = true;
}
}

如果我们更改了值,则必须发送现在将ProjectDataSet设置为ProjectServer。它将更新ProjectDataSet中更改的值。为此,我们必须检出我们的项目,对其进行更新,然后再次检入:

  / / update,如果您更改了任何内容,则
if(updatedata)
{
//首先检出项目
projectSvc.CheckOutProject(myProjectId,sessionId,自定义字段更新检出) ;

//将数据集发送到服务器以更新数据库
bool validateOnly = false;
projectSvc.QueueUpdateProject(jobId,sessionId,project,validateOnly);

//等待4秒钟,以确保作业已完成
System.Threading.Thread.Sleep(4000);

//创建一个新的jobId以检入项目
jobId = Guid.NewGuid();

//签入
bool force = false;
string sessionDescription =已更新的自定义字段;
projectSvc.QueueCheckInProject(jobId,myProjectId,force,sessionId,sessionDescription);

//再次等待4秒
System.Threading.Thread.Sleep(4000);

但是现在我们只更新了数据库。服务器仍将向我们显示旧值,而不是新值。这是因为我们尚未发布项目:

  //再次获得新的jobId发布项目
jobId = Guid.NewGuid();
bool fullPublish = true;
projectSvc.QueuePublish(jobId,myProjectId,fullPublish,null);

//也许我们应该再等一次;)
System.Threading.Thread.Sleep(4000);

最后我们完成了,我们的项目已更新!



增强功能



我对这个平台非常陌生(Project Server 2010),所以这段代码可能不是最好的例子。因此,进行了一些增强,可以使解决方案更好:




  • 睡眠功能是一个非常糟糕的解决方法,但我找不到处理同一件事的示例(像这里),并带有 2010年的QueueSystem 吗?!

  • 如果您不知道项目的Guid,而是名称,则可以通过以下函数来解决:



  ///< summary> 
///返回指定项目
///的GUID并设置此类的GUID
///< / summary>
///< param name = client>肥皂服务客户端< / param>
///< param name =项目名称>项目名称< / param>
///< returns>项目GUID< / returns>
公共Guid GetGuidByProjectName(ProjectSoapClient客户端,字符串项目名称)
{
Guid pguid = new Guid();
ProjectDataSet数据= client.ReadProjectList();

foreach(data.Tables [0] .Rows中的DataRow行)
{
if(row [1] .ToString()== projectname)//比较-大小写敏感!
{
pguid = new Guid(row [0] .ToString());
}
}

return pguid;
}


I'm new to Project Server development and was wondering if you can use the PSI to set resource custom field values.

I can't seem to find any information for a beginner at this.

I currently have web references set up for the CustomFields and the Resource web service, but am unsure how to set a custom field for a particular resource.

Any help would be really appreciated!

Thanks!

解决方案

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.

Here is a simple (maybe not the best) solution for setting custom fields:

Complete source code: http://pastebin.com/tr7CGJsW

Prepare your solution

First I've added a Service Reference to:

http: //servername/instance/_vti_bin/PSI/Project.asmx?wsdl

After that, I've edited the app.config because I had to use special credentials to login into the project server (maybe this is not necessarily for you):

...
  <security mode="TransportCredentialOnly">
    <transport clientCredentialType="Ntlm" proxyCredentialType="Ntlm" realm="" />
    <message clientCredentialType="UserName" algorithmSuite="Default" />
  </security>
    <!--<security mode="None">
        <transport clientCredentialType="None" proxyCredentialType="None"
            realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
    </security>-->
</binding>

The commented code has been created by Visual Studio

Connect and Update

Now we can create a new SoapClient which communicates with the Project Server:

//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;

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:

//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;

Then we are ready to load the ProjectDataSet from the server, find the CustomField and updating the data. It's really simple:

  1. loading the ProjectDataSet
  2. iterate trough the CustomFieldsRow
  3. checking if the CustomField matches with our Guid
  4. updating the value
  5. setting the indicator to update

//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;
    }
}

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:

//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);

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:

//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);

Finally we're done and our project is updated!

Enhancements

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:

  • The Sleep function is a very bad workaround, but I couldn't find an example which handles the same thing (like here) with a QueueSystem for 2010?!
  • If you don't know the Guid of your project, but the name, you can resolve it by following function:

/// <summary>
/// Returns the GUID for a specified project
/// and sets the guid for this class
/// </summary>
/// <param name="client">soap service client</param>
/// <param name="projectname">name of the project</param>
/// <returns>Project GUID</returns>
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;
}

这篇关于使用PSI设置自定义字段-Microsoft Project Server的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆