Project Server Online CSOM - 阅读TimePhase分配

时间:2016-11-15 17:04:16

标签: sharepoint-online ms-project-server-2013 project-online

这是我的第一个问题,所以如果这个问题不是很清楚,或者我遗漏了什么,请告诉我。

仅供参考,因此我无法附加链接,因此抱歉所有格式错误。

概述

我试图阅读(并写下)"实际工作"通过使用Microsoft提供的CSOM库获取Project Server Online中的资源。只要我正在阅读当前经过身份验证的用户的分配,读取和写入作业和实际工作就会完美运行。如果我尝试为另一个资源读取此内容,则会收到GeneralSecurityAccessDenied错误。

我过去使用Impersonation这样做了,如果用户有StatusBrokerPermission,它应该在后台透明地调用,但它似乎并不适合我。模拟在2013年已被删除,因此不再是一种选择。

问题摘要

CSOM应该透明地启用状态扩展,以允许对当前经过身份验证的用户以外的资源进行状态更新(只要用户具有状态代理权限)。这适用于添加新分配,但在尝试通过TimePhased分配更新实际TimePhased小时时不起作用。无法查询分配,因此,我们无法调用SubmitAllStatusUpdates来提交小时数。

研究

  1. CSOM的使用方案:https:// msdn.microsoft.com/en-us/library/office/jj163082(v=office.15).aspx#pj15_WhatTheCSOM_UsageScenarios

  2. 模拟已弃用:https:// msdn.microsoft.com/en-us/library/office/ee767690(v=office.15).aspx#pj15_WhatsNew_Deprecated)

  3. 图片:Supposed to read on behalf of another user...

    1. 有同样问题的人#1:https:// social.technet.microsoft.com/Forums/projectserver/en-US/dccdb543-18a1-4a0e-a948-5d861305516e/how-to-get-资源分配 - 总结 - 视图 - 数据项目的服务器在线2013?论坛= projectonline)

    2. 有相同问题的人#2:http:// uzzai.com/ZB43wp95/ps2013-app-how-to-read-and-update-timephased-data-with-jsom-javascript-csom。 HTML

    3. 有同样问题的人#4:https:// social.technet.microsoft.com/Forums/Sharepoint/en-US/be27d497-e959-44b6-97cb-8f19fe0278fe/csom-how-to-设置timephase-数据上的赋值?论坛= project2010custprog

    4. 我试过的其他事情

      1. 将CSOM与MsOnlineClaimsHelper一起使用,为用户检索FedAuth cookie(并使用CookieContainer分配它们)。
      2. 使用REST / OData API。 a)https:// URL.sharepoint.com/sites/pwa/_api/ProjectServer/EnterpriseResources('c39ba8f1-00fe-e311-8894-00155da45f0e')/Assignments/GetTimePhaseByUrl(start=' 2014年12月9日',结束=' 2014年12月9日')/分配
      3. 启用" StatusBrokerPermission"对于用户
      4. 取消选中“仅允许通过任务和时间表进行任务更新。”服务器设置屏幕中的选项(任务设置和显示)。
      5. 创建SharePoint托管的应用程序并使用与上述CSOM代码等效的JSOM代码。 a)我们编写的代码是从SharePoint应用程序中执行的JavaScript,因此我们不需要提供身份验证。登录的用户具有StatusBrokerPermission。
      6. 使用提供商托管的SharePoint应用并使用上面的CSOM代码。我们尝试使用上述CSOM的所有身份验证方法,并进行了额外的测试: a)使用Fiddler查看由SharePoint应用程序身份验证设置的FedAuth cookie,并覆盖WebRequest以手动插入FedAuth / rtFA cookie:webRequestEventArgs.WebRequestExecutor.WebRequest.CookieContainer = getStaticCookieContainer();
      7. 使用时间表提交时间分段数据。 a)我们只能为当前经过身份验证的用户创建时间表,并且无法使用他无法使用的项目/作业填充时间表行(或者抛出GeneralItemDoesNotExist错误)。
      8. 使用fiddler作为其他用户手动发出“SubmitAllStatusUpdates”CSOM请求。 a)此测试的目的是确定我们是否可以编写时间分段数据,即使我们无法读取它。
      9. 确保项目已签出给当前用户。
      10. 对资源使用管理委派。
      11. 在项目权限内设置所有可用选项。
      12. 使用Project Web UI输入其他资源的TimePhased数据。
      13. 使用SharePoint权限模式而不是项目权限模式。
      14. 代码

        See failing code screenshot here

            using System;
            using System.Security;
            using Microsoft.ProjectServer.Client;
            using Microsoft.SharePoint.Client;
            namespace ProjectOnlineActuals
            {
                static class Program
                {
                    const string projectSite = "https://URL.sharepoint.com/sites/pwa/";
                    private const string edward = "c39ba8f1-00fe-e311-8894-00155da45f0e";
                    private const string admin = "8b1bcfa4-1b7f-e411-af75-00155da4630b";
        
                    static void Main(string[] args)
                    {
                        TestActuals();
                    }
        
                    private static void TestActuals()
                    {
                        Console.WriteLine("Attempting test # 1 (login: admin, resource: admin)");
                        TestActuals("admin@URL.onmicrosoft.com", "123", admin);
        
                        Console.WriteLine("Attempting test # 2 (login: admin, resource: edward)");
                        TestActuals("adminy@hmssoftware.onmicrosoft.com", "123", edward);
                        Console.ReadLine();
                    }
        
                    private static void TestActuals(string username, string password, string resourceID)
                    {
                        try
                        {
                            using (ProjectContext context = new ProjectContext(projectSite))
                            {
                                DateTime startDate = DateTime.Now.Date;
                                DateTime endDate = DateTime.Now.Date;
                                Login(context, username, password);
                                context.Load(context.Web); // Query for Web
                                context.ExecuteQuery(); // Execute
        
                                Guid gResourceId = new Guid(resourceID);
                                EnterpriseResource enterpriseResource = context.EnterpriseResources.GetByGuid(gResourceId);
                                context.Load(enterpriseResource, p => p.Name, p => p.Assignments, p => p.Email);
                                Console.Write("Loading resource...");
                                context.ExecuteQuery();
                                Console.WriteLine("done! {0}".FormatWith(enterpriseResource.Name));
        
                                Console.Write("Adding new resource assignment to collection...");
                                enterpriseResource.Assignments.Add(new StatusAssignmentCreationInformation
                                {
                                    Comment = "testing comment - 2016-02-17",
                                    ProjectId = new Guid("27bf182c-2339-e411-8e76-78e3b5af0525"),
        
                                    Task = new StatusTaskCreationInformation
                                    {
                                        Start = DateTime.Now,
                                        Finish = DateTime.Now.AddDays(2),
                                        Name = "testing - 2016-02-17",
                                    }
                                });
                                Console.WriteLine("done!");
        
                                Console.Write("Trying to save new resource assignment...");
                                enterpriseResource.Assignments.Update();
                                context.ExecuteQuery();
                                Console.WriteLine("done!");
        
                                Console.Write("Loading TimePhase...");
                                TimePhase timePhase = enterpriseResource.Assignments.GetTimePhase(startDate.Date, endDate.Date);
                                context.ExecuteQuery();
                                Console.WriteLine("done!");
        
                                Console.Write("Loading TimePhase assignments...");
                                context.Load(timePhase.Assignments);
                                context.ExecuteQuery();
                                Console.WriteLine("done! Found {0} assignments.".FormatWith(timePhase.Assignments.Count));
        
                                Console.WriteLine("Updating TimePhase assignments...");
                                foreach (var assignment in timePhase.Assignments)
                                {
                                    Console.WriteLine("Updating assignment: {0}. ActualWork: {1}".FormatWith(assignment.Name, assignment.ActualWork));
                                    assignment.ActualWork = "9h";
                                    assignment.RegularWork = "3h";
                                    assignment.RemainingWork = "0h";
                                }
                                timePhase.Assignments.SubmitAllStatusUpdates("Status update comment test 2016-02-17");
                                context.ExecuteQuery();
                                Console.WriteLine("done!");
        
                                Console.WriteLine("Success (retrieved & updated {0} time phase assignments)!".FormatWith(timePhase.Assignments.Count));
                            }
                        }
                        catch (Exception ex)
                        {
                            if (ex.ToString().Contains("GeneralSecurityAccessDenied"))
                                Console.WriteLine("ERROR! - GeneralSecurityAccessDenied");
                            else
                                throw;
                        }
                        finally
                        {
                            Console.WriteLine();
                            Console.WriteLine();
                        }
                    }
        
                    private static void Login(ProjectContext projContext, string username, string password)
                    {
                        var securePassword = new SecureString();
                        foreach (char c in password)
                            securePassword.AppendChar(c);
        
                        projContext.Credentials = new SharePointOnlineCredentials(username, securePassword);
                    }
        
                    static string FormatWith(this string str, params object[] args)
                    {
                        return String.Format(str, args);
                    }
                }
            }
        

        任何人都可以帮忙吗?

0 个答案:

没有答案