Events.ReadEventsList 方法
获取的 Project Server 事件的列表。
命名空间: WebSvcEvents
程序集: ProjectServerServices(位于 ProjectServerServices.dll 中)
语法
声明
<SoapDocumentMethodAttribute("https://schemas.microsoft.com/office/project/server/webservices/Events/ReadEventsList", RequestNamespace := "https://schemas.microsoft.com/office/project/server/webservices/Events/", _
ResponseNamespace := "https://schemas.microsoft.com/office/project/server/webservices/Events/", _
Use := SoapBindingUse.Literal, ParameterStyle := SoapParameterStyle.Wrapped)> _
Public Function ReadEventsList As EventsDataSet
用法
Dim instance As Events
Dim returnValue As EventsDataSet
returnValue = instance.ReadEventsList()
[SoapDocumentMethodAttribute("https://schemas.microsoft.com/office/project/server/webservices/Events/ReadEventsList", RequestNamespace = "https://schemas.microsoft.com/office/project/server/webservices/Events/",
ResponseNamespace = "https://schemas.microsoft.com/office/project/server/webservices/Events/",
Use = SoapBindingUse.Literal, ParameterStyle = SoapParameterStyle.Wrapped)]
public EventsDataSet ReadEventsList()
返回值
类型:WebSvcEvents.EventsDataSet
EventsDataSet包括事件 ID、 事件名称和事件的源。
备注
事件源是 Project Server 实体,如项目、 日历、 自定义字段、 LookupTable,等等。事件名称包括前期事件和后期事件。例如,项目发布前期事件触发时进行发布的项目的 PSI 调用和发布项目之前。已发布数据库中保存项目后,将触发发布项目的后期事件。
Project Server 权限
权限 |
说明 |
---|---|
允许用户管理的服务器端事件处理程序。全局权限。 |
示例
下面的示例演示使用ReadEventsList方法。创建和修改事件处理程序并后两个单独的 XML 文件中写入的未修改的数据集和已修改数据集,应用程序使用ReadEventsList检索所有 Project Server 事件的列表,然后将它们写入第三个的 XML 文件。
该示例使用 ProjectServerServices.dll 代理程序集在SvcEvent命名空间。
备注
在某些情况下,可能需要长达 60 秒的事件处理程序关联过程完成。必须设置休眠间隔,以便没有足够的时间才能完成此过程。否则,索引错误的数据集可能终止应用程序。如果应用程序不运行时没有完成上一步,结果将不可靠。本示例中,创建事件处理程序允许的时间为 45 秒,并允许访问的事件处理的时间为 5 秒。在特定环境中,实验需要确定所需完成这些操作的时间量。
The ConfigClientEndpoints method uses an app.config file for setting the WCF binding, behavior, and endpoint. For information about creating a PSI proxy assembly and an app.config file, see Project 2013 中基于 WCF 的代码示例的先决条件.
using System;
using System.Threading;
using System.Diagnostics;
using System.ServiceModel;
using System.Xml;
using Microsoft.SharePoint;
using PSLibrary = Microsoft.Office.Project.Server.Library;
using Microsoft.Office.Project.Server.Events;
namespace ManageEventHandler
{
class Program
{
private static SvcEvents.EventsClient eventsClient;
private const string ENDPOINT_EVENTS = "basicHttp_Events";
// Change the output directory for your computer.
private const string OUTPUT_FILES = @"C:\Project\Samples\Output\";
private static string outFileCreatedEH;
private static string outFileUpdatedEH;
private static string outFileAllEvents;
private static int dbWriteInterval = 35000;
private static int dbReadInterval = 5000;
static void Main(string[] args)
{
Console.WriteLine("\nStart Time: {0}", DateTime.Now.ToString());
Stopwatch timer = new Stopwatch();
timer.Start();
// Set path and file name for output files and configure web service client endpoints.
outFileCreatedEH = OUTPUT_FILES + "MEH_CreatedHandler.xml";
outFileUpdatedEH = OUTPUT_FILES + "MEH_CreatedHandlerUpdated.xml";
outFileAllEvents = OUTPUT_FILES + "MEH_AllEvents.xml";
ConfigClientEndpoints();
try
{
// Create an instance of an event handler dataset with one row.
SvcEvents.EventHandlersDataSet eventHandlerDS = new SvcEvents.EventHandlersDataSet();
SvcEvents.EventHandlersDataSet.EventHandlersRow ehRow = eventHandlerDS.EventHandlers.NewEventHandlersRow();
// Add CustomFieldsCreated event handler registration information to the row.
Guid uid = Guid.NewGuid();
ehRow.EventHandlerUid = uid;
ehRow.Name = "Custom Fields Created Event Handler";
ehRow.AssemblyName =
"TestCreatedCustomField, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f94f2907cf07bc7c";
ehRow.ClassName =
"Microsoft.SDK.Project.Samples.EventHandlers.TestCreatedCustomField.WriteCustomFieldCreatedEvent";
ehRow.EventId = (int)SvcEvents.PSEventID.CustomFieldsCreated;
ehRow.Description = "Test the OnCreated event handler for custom fields.";
ehRow.Order = 1;
eventHandlerDS.EventHandlers.AddEventHandlersRow(ehRow.EventHandlerUid, ehRow.Name,
ehRow.AssemblyName, ehRow.ClassName, ehRow.EventId, ehRow.Description, ehRow.Order);
// Associate the event handler with the CustomFieldCreated event.
eventsClient.CreateEventHandlerAssociations(eventHandlerDS);
DisplayComment("\nCreating and storing a CustomFieldCreated event handler...", "Yellow");
Thread.CurrentThread.Join(dbWriteInterval);
DisplayTime(timer);
// Retrieve the new event handler from the dataset by using its event identifier.
SvcEvents.EventHandlersDataSet initEvDS = eventsClient.ReadEventHandlerAssociationsForEvent(SvcEvents.PSEventID.CustomFieldsCreated);
DisplayComment("\nRetrieving the new event handler from the database...", "Yellow");
Thread.CurrentThread.Join(dbReadInterval);
DisplayTime(timer);
initEvDS.WriteXml(outFileCreatedEH);
string currDesc = "\nDescription field of the retrieved event handler: \n " + initEvDS.EventHandlers[0].Description;
DisplayComment(currDesc, "White");
// Modify the event handler description field and update the dataset.
initEvDS.EventHandlers[0].Description = "This is the modified event handler description.";
eventsClient.UpdateEventHandlerAssociations(initEvDS);
DisplayComment("\nModifying the description field and updating the event handler...", "Yellow");
Thread.CurrentThread.Join(dbWriteInterval);
DisplayTime(timer);
// Retrieve the event handler from the dataset by using its event identifier.
SvcEvents.EventHandlersDataSet updEvDS = eventsClient.ReadEventHandlerAssociationsForEvent(SvcEvents.PSEventID.CustomFieldsCreated);
DisplayComment("\nRetrieving the updated event handler...", "Yellow");
Thread.CurrentThread.Join(dbReadInterval);
DisplayTime(timer);
currDesc = "\nDescription field of the updated event handler: \n " + updEvDS.EventHandlers[0].Description;
DisplayComment(currDesc, "White");
updEvDS.WriteXml(outFileUpdatedEH);
// Compare the original and the modified description fields to verify that the dataset was updated.
int same = eventHandlerDS.EventHandlers[0].Description.CompareTo(updEvDS.EventHandlers[0].Description);
if (same == 0)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("\nThe description field was not modified during the alloted time.");
Console.ResetColor();
}
else
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine(
"\n\nThe CustomFieldCreated event handler description has been modified \n from '{0}' \n to '{1}'",
eventHandlerDS.EventHandlers[0].Description, updEvDS.EventHandlers[0].Description, ".");
Console.ResetColor();
}
// Read the list of all events and write them to an output file.
SvcEvents.EventsDataSet AllEventsDS = new SvcEvents.EventsDataSet();
AllEventsDS = eventsClient.ReadEventsList();
AllEventsDS.WriteXml(outFileAllEvents);
}
catch (FaultException fault)
{
Console.ForegroundColor = ConsoleColor.Red;
// Use the WCF FaultException, because the ASMX SoapException does not
// exist in a WCF-based application.
WriteFaultOutput(fault);
Console.ForegroundColor = ConsoleColor.Yellow;
}
finally
{
DisplayTime(timer);
Console.ResetColor();
Console.Write("\nPress any key to exit... ");
Console.ReadKey(true);
}
}
// Use the endpoint defined in app.config to configure the client.
public static void ConfigClientEndpoints()
{
eventsClient = new SvcEvents.EventsClient(ENDPOINT_EVENTS);
}
public static void DisplayTime(Stopwatch timer)
{
// Pause the timer and display the current accumulated time in seconds.
timer.Stop();
TimeSpan ts = timer.Elapsed;
string elapsedTime = String.Format("\n\tElapsed time: {0:F4} seconds ({1:F2} minutes) ",
ts.TotalSeconds, ts.TotalMinutes);
Console.WriteLine(elapsedTime);
timer.Start();
}
public static void DisplayComment(string comment, string color)
{
switch (color)
{
case "White": Console.ForegroundColor = ConsoleColor.White; break;
case "Red": Console.ForegroundColor = ConsoleColor.Red; break;
case "Yellow": Console.ForegroundColor = ConsoleColor.Yellow; break;
case "Cyan": Console.ForegroundColor = ConsoleColor.Cyan; break;
default: Console.ForegroundColor = ConsoleColor.White; break;
}
Console.WriteLine("\n\n" + comment);
Console.ResetColor();
}
// Extract a PSClientError object from the WCF FaultException object, and
// then display the exception details and each error in the PSClientError stack.
private static void WriteFaultOutput(FaultException fault)
{
string errAttributeName;
string errAttribute;
string errOut;
string errMess = "".PadRight(30, '=') + "\r\n"
+ "Error details: \n" + "\r\n";
PSLibrary.PSClientError error = Helpers.GetPSClientError(fault, out errOut);
errMess += errOut;
PSLibrary.PSErrorInfo[] errors = error.GetAllErrors();
PSLibrary.PSErrorInfo thisError;
for (int i = 0; i < errors.Length; i++)
{
thisError = errors[i];
errMess += "\r\n".PadRight(30, '=') + "\r\nPSClientError output:\r\n\n";
errMess += thisError.ErrId.ToString() + "\n";
for (int j = 0; j < thisError.ErrorAttributes.Length; j++)
{
errAttributeName = thisError.ErrorAttributeNames()[j];
errAttribute = thisError.ErrorAttributes[j];
errMess += "\r\n\t" + errAttributeName
+ ": " + errAttribute;
}
}
Console.WriteLine(errMess);
}
// Helper methods: GetPSClientError.
class Helpers
{
// Helper method: GetPSClientError.
/// <summary>
/// Extract a PSClientError object from the ServiceModel.FaultException,
/// for use in output of the GetPSClientError stack of errors.
/// </summary>
/// <param name="e"></param>
/// <param name="errOut">Shows that FaultException has more information
/// about the errors than PSClientError has. FaultException can also contain
/// other types of errors, such as failure to connect to the server.</param>
/// <returns>PSClientError object, for enumerating errors.</returns>
public static PSLibrary.PSClientError GetPSClientError(FaultException e,
out string errOut)
{
const string PREFIX = "GetPSClientError() returns null: ";
errOut = string.Empty;
PSLibrary.PSClientError psClientError = null;
if (e == null)
{
errOut = PREFIX + "Null parameter (FaultException e) passed in.";
psClientError = null;
}
else
{
// Get a ServiceModel.MessageFault object.
var messageFault = e.CreateMessageFault();
if (messageFault.HasDetail)
{
using (var xmlReader = messageFault.GetReaderAtDetailContents())
{
var xml = new XmlDocument();
xml.Load(xmlReader);
var serverExecutionFault = xml["ServerExecutionFault"];
if (serverExecutionFault != null)
{
var exceptionDetails = serverExecutionFault["ExceptionDetails"];
if (exceptionDetails != null)
{
try
{
errOut = exceptionDetails.InnerXml + "\r\n";
psClientError =
new PSLibrary.PSClientError(exceptionDetails.InnerXml);
}
catch (InvalidOperationException ex)
{
errOut = PREFIX + "Unable to convert fault exception info ";
errOut += "a valid Project Server error message. Message: \n\t";
errOut += ex.Message;
psClientError = null;
}
}
else
{
errOut = PREFIX + "The FaultException e is a ServerExecutionFault, "
+ "but does not have ExceptionDetails.";
}
}
else
{
errOut = PREFIX + "The FaultException e is not a ServerExecutionFault.";
}
}
}
else // There is no detail in the MessageFault.
{
errOut = PREFIX + "The FaultException e does not have any detail.";
}
}
errOut += "\r\n" + e.ToString() + "\r\n";
return psClientError;
}
}
}
}
下面是应用程序保存 MEH_CreatedHandler.xml 输出文件的示例。
<?xml version="1.0" standalone="true"?>
<EventHandlersDataSet xmlns="https://schemas.microsoft.com/office/project/server/webservices/EventHandlersDataSet/">
<EventHandlers>
<EventHandlerUid>d4d0a891-02cd-4c5a-9c08-a3f88b295270</EventHandlerUid>
<Name>Custom Fields Created Event Handler</Name>
<AssemblyName>TestCreatedCustomField, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f94f2907cf07bc7c</AssemblyName> <ClassName>Microsoft.SDK.Project.Samples.EventHandlers.TestCreatedCustomField.WriteCustomFieldCreatedEvent</ClassName> <EventId>26</EventId>
<Description>Test the OnCreated event handler for custom fields.</Description>
<Order>1</Order>
</EventHandlers>
</EventHandlersDataSet>
下面是应用程序保存 MEH_CreatedHandlerUpdated.xml 输出文件的示例。
<?xml version="1.0" standalone="true"?>
<EventHandlersDataSet xmlns="https://schemas.microsoft.com/office/project/server/webservices/EventHandlersDataSet/">
<EventHandlers>
<EventHandlerUid>d4d0a891-02cd-4c5a-9c08-a3f88b295270</EventHandlerUid>
<Name>Custom Fields Created Event Handler</Name>
<AssemblyName>TestCreatedCustomField, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f94f2907cf07bc7c</AssemblyName> <ClassName>Microsoft.SDK.Project.Samples.EventHandlers.TestCreatedCustomField.WriteCustomFieldCreatedEvent</ClassName> <EventId>26</EventId>
<Description>This is the modified event handler description.</Description>
<Order>1</Order>
</EventHandlers>
</EventHandlersDataSet>
下面是应用程序保存 MEH_AllEvents.xml 输出文件的示例。
<?xml version="1.0" standalone="true"?>
<EventsDataSet xmlns="https://schemas.microsoft.com/office/project/server/webservices/EventsDataSet/"> -<Event> <EventId>0</EventId><SourceName>Admin</SourceName> <EventName>ReportingPeriodUpdated</EventName></Event>
<Event><EventId>1</EventId><SourceName>Admin</SourceName> <EventName>ReportingPeriodUpdating</EventName></Event>
<Event><EventId>2</EventId><SourceName>Admin</SourceName> <EventName>LineClassUpdated</EventName></Event>
<Event><EventId>3</EventId><SourceName>Admin</SourceName> <EventName>LineClassUpdating</EventName></Event>
<Event><EventId>4</EventId><SourceName>Admin</SourceName> <EventName>StatusReportsDeleted</EventName></Event>
<Event><EventId>5</EventId><SourceName>Admin</SourceName> <EventName>StatusReportsDeleting</EventName></Event>
<Event><EventId>10</EventId><SourceName>Admin</SourceName> <EventName>AdSyncERPSynchronized</EventName></Event>
…
<Event><EventId>197</EventId><SourceName>UserDelegation</SourceName> <EventName>Activating</EventName></Event>
<Event><EventId>198</EventId><SourceName>UserDelegation</SourceName> <EventName>Changed</EventName></Event>
<Event><EventId>199</EventId><SourceName>UserDelegation</SourceName> <EventName>Changing</EventName></Event>
<Event><EventId>200</EventId><SourceName>UserDelegation</SourceName> <EventName>Deactivated</EventName></Event>
<Event><EventId>201</EventId><SourceName>UserDelegation</SourceName> <EventName>Deactivating</EventName></Event>
</EventsDataSet>