C# EWS:';设置操作对于属性';无效;编辑所需与会者时

C# EWS:';设置操作对于属性';无效;编辑所需与会者时,c#,exchange-server,exchangewebservices,ews-managed-api,C#,Exchange Server,Exchangewebservices,Ews Managed Api,在您将此作为副本关闭之前,请查看另一个标题类似的问题,该问题没有答案,他只是将其标记为已回答并离开 每当我试图编辑约会中的requiredAttenders属性时,我都会从EWS管理API中得到这个可爱的描述性错误 设置操作对属性无效。 查看异常详细信息表明,确实是requiredAttenders属性导致了问题,但我不知道原因 我用来连接到该服务的凭据是会议组织者的凭据,我甚至尝试冒充该用户,但运气不佳。挠头想弄清楚这里出了什么问题 以下是导致问题的更新例程的相关部分 PropertySet

在您将此作为副本关闭之前,请查看另一个标题类似的问题,该问题没有答案,他只是将其标记为已回答并离开

每当我试图编辑约会中的
requiredAttenders
属性时,我都会从EWS管理API中得到这个可爱的描述性错误

设置操作对属性无效。

查看异常详细信息表明,确实是
requiredAttenders
属性导致了问题,但我不知道原因

我用来连接到该服务的凭据是会议组织者的凭据,我甚至尝试冒充该用户,但运气不佳。挠头想弄清楚这里出了什么问题

以下是导致问题的更新例程的相关部分

PropertySet props = new PropertySet(
        AppointmentSchema.Start,
        AppointmentSchema.End,
        AppointmentSchema.Id,
        AppointmentSchema.Organizer,
        AppointmentSchema.Subject,
        AppointmentSchema.Body,
        AppointmentSchema.RequiredAttendees);
props.RequestedBodyType = BodyType.Text;

Appointment appointment = Appointment.Bind(_service, new ItemId(appointmentId), props);

if (IsResource(appointment.Organizer.Address) && appointment.Organizer.Address != resourceId)
{
    /*
    * removed for brevity, no attendee manipulation here
    */
}
else 
{
    List<Attendee> remove = new List<Attendee>();
    foreach (var attendee in appointment.RequiredAttendees)
    {
        if (IsResource(attendee.Address) && attendee.Address != resourceId)
        {
            remove.Add(attendee);
        }
    }
    remove.ForEach(a => appointment.RequiredAttendees.Remove(a));
    if (!appointment.RequiredAttendees.Any(a => a.Address == resourceId))
    {
        appointment.RequiredAttendees.Add(resourceId);
    }
}

/*
* removed for brevity, no attendee manipulation here
*/

if (IsAvailable(resourceId, startTime, endTime, appointmentId))
    appointment.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToAllAndSaveCopy);
else
    throw new RoomUnavailableException();
PropertySet props=新属性集(
AppointmentSchema.Start,
任命模式。结束,
AppointSchema.Id,
AppointSchema.Organizer,
任命模式。主题,
任命模式。正文,
任命模式(所需与会者);
props.RequestedBodyType=BodyType.Text;
Appointment=Appointment.Bind(_服务,新项目ID(appointmentId),道具);
if(IsResource(appointment.Organizer.Address)&&appointment.Organizer.Address!=resourceId)
{
/*
*为简洁起见已删除,此处无与会者操纵
*/
}
其他的
{
List remove=新列表();
foreach(预约中的var与会者。必选与会者)
{
if(IsResource(attendee.Address)&&attendee.Address!=资源ID)
{
删除。添加(与会者);
}
}
remove.ForEach(a=>appointment.requiredAttenders.remove(a));
如果(!appoint.requiredAttenders.Any(a=>a.Address==resourceId))
{
约会。RequiredAttenders.Add(resourceId);
}
}
/*
*为简洁起见已删除,此处无与会者操纵
*/
if(可用(资源ID、开始时间、结束时间、任命ID))
更新(ConflictResolutionMode.AlwaysOverwrite、SendInvitations或CancellationMode.SendToAllAndSaveCopy);
其他的
抛出新的RoomUnavailableException();
请求跟踪:

<Trace Tag = "EwsRequest" Tid="14" Time="2017-09-25 20:20:24Z" Version="15.00.0847.030">
  <?xml version = "1.0" encoding="utf-8"?>
  <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
      <t:RequestServerVersion Version = "Exchange2013" />
    </ soap:Header>
    <soap:Body>
      <m:UpdateItem ConflictResolution = "AlwaysOverwrite" SendMeetingInvitationsOrCancellations="SendToAllAndSaveCopy">
        <m:ItemChanges>
          <t:ItemChange>
            <t:ItemId Id = "AAMkAGEwYWRjZjA3LWNlZjAtNDI2Ny05ZjQwLWUzYWZjOThhMjkzNwBGAAAAAABWdX+yf6THTpO/1LYpoG6xBwD6lEwS6u8XQbDhIlTh/X/UAAAAAAENAAD6lEwS6u8XQbDhIlTh/X/UAAAi3oSdAAA=" ChangeKey="DwAAABYAAAD6lEwS6u8XQbDhIlTh/X/UAAAi3ocU" />
            <t:Updates>
              <t:SetItemField>
                <t:FieldURI FieldURI = "calendar:RequiredAttendees" />
                < t:CalendarItem>
                  <t:RequiredAttendees>
                    <t:Attendee>
                      <t:Mailbox>
                        <t:Name>Exchange Test</t:Name>
                        <t:EmailAddress>etest @supertester.com</t:EmailAddress>
                        <t:RoutingType>SMTP</t:RoutingType>
                        <t:MailboxType>Mailbox</t:MailboxType>
                      </t:Mailbox>
                    </t:Attendee>
                    <t:Attendee>
                      <t:Mailbox>
                        <t:EmailAddress>redroom @supertester.com</t:EmailAddress>
                      </t:Mailbox>
                    </t:Attendee>
                  </t:RequiredAttendees>
                </t:CalendarItem>
              </t:SetItemField>
            </t:Updates>
          </t:ItemChange>
        </m:ItemChanges>
      </m:UpdateItem>
    </soap:Body>
  </soap:Envelope>
</Trace>


交换测试
etest@supertest.com
SMTP
邮箱
redroom@supertest.com
响应跟踪:

<Trace Tag = "EwsResponse" Tid="14" Time="2017-09-25 20:20:24Z" Version="15.00.0847.030">
  <?xml version = "1.0" encoding="utf-8"?>
  <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Header>
      <h:ServerVersionInfo MajorVersion = "15" MinorVersion="1" MajorBuildNumber="225" MinorBuildNumber="41" Version="V2_48" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
    </s:Header>
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <m:UpdateItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
        <m:ResponseMessages>
          <m:UpdateItemResponseMessage ResponseClass = "Error" >
            <m:MessageText>Set action is invalid for property.</m:MessageText>
            <m:ResponseCode>ErrorInvalidPropertySet</m:ResponseCode>
            <m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
            <m:MessageXml>
              <t:FieldURI FieldURI = "calendar:RequiredAttendees" />
            </m:MessageXml>
            <m:Items />
          </m:UpdateItemResponseMessage>
        </m:ResponseMessages>
      </m:UpdateItemResponse>
    </s:Body>
  </s:Envelope>
</Trace>

设置操作对属性无效。
ErrorInvalidPropertySet
0
请注意,“RequiredAttenders”对象只有在它是会议时才会被填充

在您的else语句中添加此支票

if(appointment.IsMeeting)
{
  List<Attendee> remove = new List<Attendee>();
 foreach (var attendee in appointment.RequiredAttendees)
 {
    if (IsResource(attendee.Address) && attendee.Address != resourceId)
    {
        remove.Add(attendee);
    }
 }
 remove.ForEach(a => appointment.RequiredAttendees.Remove(a));
 if (!appointment.RequiredAttendees.Any(a => a.Address == resourceId))
 {
    appointment.RequiredAttendees.Add(resourceId);
 }
}
if(约会.IsMeeting)
{

列表

非常感谢Glen Scales为我指出了正确的方向

检索约会时,我使用了以下代码:

CalendarFolder calendar = CalendarFolder.Bind(_service, new FolderId(WellKnownFolderName.Calendar, resourceId), PropertySet.IdOnly);
CalendarView cView = new CalendarView(startDate, endDate, _maxAppointments);
cView.PropertySet = new PropertySet(PropertySet.IdOnly);
FindItemsResults<Appointment> appointments = calendar.FindAppointments(cView);

我建议您启用跟踪并发布跟踪响应,这可能会告诉您更多有关错误发生原因的信息。@GlenScales我添加了跟踪。仍然不确定这为什么不起作用。您是在尝试修改原始约会还是副本?例如,您似乎在尝试修改位于会议室的约会实例ndar,即使你模拟组织者也不起作用。唯一可以修改的副本是存储在组织者日历中的原始项目。@GlenScales啊,好吧,可能是这样,我是个新手,我不知道两者之间有什么不同。非常感谢,我必须看看如何找到原始会议.@GlenScales就是这样,非常感谢!IsMeeting是真的
appointment = FindOrganizerAppointment(appointment);

/// <summary>
/// Finds the related Appointment.
/// </summary>
/// <param name="appointment">The appointment whose original is to be found.</param>
/// <returns></returns>
private Appointment FindOrganizerAppointment(Appointment appointment)
{
    try
    {
        Impersonate(appointment.Organizer.Address);

        var filter = new SearchFilter.IsEqualTo
        {
            PropertyDefinition = new ExtendedPropertyDefinition
                (DefaultExtendedPropertySet.Meeting, 0x03, MapiPropertyType.Binary),
            Value = GetObjectIdStringFromUid(appointment.ICalUid)
        };

        var view = new ItemView(1) { PropertySet = new PropertySet(BasePropertySet.FirstClassProperties) };

        return _service.FindItems(WellKnownFolderName.Calendar, filter, view).Items[0] as Appointment;
    }
    catch (Exception e)
    {
         throw e;
    }
    finally
    {
        DisableImpersonation();
    }
}

/// <summary>
/// Gets the object id string from uid.
/// <remarks>The UID is formatted as a hex-string and the GlobalObjectId is displayed as a Base64 string.</remarks>
/// </summary>
/// <param name="id">The uid.</param>
/// <returns></returns>
private static string GetObjectIdStringFromUid(string id)
{
    var buffer = new byte[id.Length / 2];
    for (int i = 0; i < id.Length / 2; i++)
    {
        var hexValue = byte.Parse(id.Substring(i * 2, 2), System.Globalization.NumberStyles.AllowHexSpecifier);
        buffer[i] = hexValue;
    }
    return Convert.ToBase64String(buffer);
}