我如何(正确)从 EWS 继承类,例如约会?

Oli*_*ane 4 c# exchange-server xml-serialization exchangewebservices

同样的问题:https : //stackoverflow.com/questions/11294207/exchange-web-services-argumentexception-using-my-own-contact-class

我正在尝试从 Microsoft.Exchange.WebServices.Data.Appointment 编写派生类。但是,如果不抛出似乎是序列化错误的内容,则无法保存派生类。即使我不对派生类进行任何修改,也会发生这种情况。

这有效:

public void CreateTestAppointment() {
        Appointment appointment = new Appointment(Exchange) {
            ItemClass = "IPM.Appointment", //Exchange Specific. Dont touch unless you     know what this does. I sure as hell don't.
            Subject = string.Format("{0} Test", "Oliver")
        };
        appointment.RequiredAttendees.Add("okane@cottinghambutler.com");
        appointment.Body = new MessageBody {
            Text = "Meeting invite body text placeholder"
        };

        //Add item to the appropriate categories
        appointment.Categories.Add(string.Format("[C]{0}", "Arbitrary Client Group"));

        // Add calendar properties to the appointment.
        appointment.Start = DateTime.Now.AddMinutes(10);
        appointment.End = DateTime.Now.AddMinutes(30);

        appointment.Save(Hc360CallCalendarFolderId, SendInvitationsMode.SendOnlyToAll);
    }
Run Code Online (Sandbox Code Playgroud)

但这不会:

 public void CreateTestAppointment() {
        InheritedAppointment appointment = new InheritedAppointment(Exchange) {
            ItemClass = "IPM.Appointment", //Exchange Specific. Dont touch unless you know what this does. I sure as hell don't.
            Subject = string.Format("{0} Test", "Oliver")
        };
        appointment.RequiredAttendees.Add("okane@cottinghambutler.com");
        appointment.Body = new MessageBody {
            Text = "Meeting invite body text placeholder"
        };

        //Add item to the appropriate categories
        appointment.Categories.Add(string.Format("[C]{0}", "Arbitrary Client Group"));

        // Add calendar properties to the appointment.
        appointment.Start = DateTime.Now.AddMinutes(10);
        appointment.End = DateTime.Now.AddMinutes(30);

        appointment.Save(Hc360CallCalendarFolderId, SendInvitationsMode.SendOnlyToAll);
    }
Run Code Online (Sandbox Code Playgroud)

这很奇怪,因为我实际上并没有在派生类中做任何事情。

    public class InheritedAppointment : Microsoft.Exchange.WebServices.Data.Appointment {
    public InheritedAppointment(ExchangeService serivce)
        : base(serivce) {

    }}
Run Code Online (Sandbox Code Playgroud)

看起来这正在被序列化为 XML,并且某些值为 null,但我终生无法弄清楚它是什么。这是原始错误

测试名称:TestMeetingCreation 测试全名:Hc360LibTests.UnitTest1.TestMeetingCreation 测试来源:c:\Users\okane\Documents\Visual Studio 2012\Projects\HealthCheck360OutlookCallScheduleHelper\Hc360LibTests\UnitTest1.cs:第 15 行:测试失败:D :00.5728502

结果消息:测试方法 Hc360LibTests.UnitTest1.TestMeetingCreation 抛出异常:System.ArgumentException:空字符串 '' 不是有效的本地名称。结果 StackTrace:在 System.Xml.XmlWellFormedWriter.WriteStartElement(String prefix, String localName, String ns) at Microsoft.Exchange.WebServices.Data.EwsServiceXmlWriter.WriteStartElement(XmlNamespace xmlNamespace, String localName) at Microsoft.Exchange.WebServices.Data.PropertyBag .WriteToXml(EwsServiceXmlWriter writer) 在 Microsoft.Exchange.WebServices.Data.CreateRequest 2.WriteElementsToXml(EwsServiceXmlWriter writer) at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.WriteBodyToXml(EwsServiceXmlWriter writer) at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.WriteToXml(EwsServiceXmlWriter writer) at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.EmitRequest(IEwsHttpWebRequest request) at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.BuildEwsHttpWebRequest() at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ValidateAndEmitRequest(IEwsHttpWebRequest& request) at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest1.Execute() 在 Microsoft.Exchange.WebServices.Data.ExchangeService.InternalCreateItems(IEnumerable 1 items, FolderId parentFolderId, Nullable1 messageDisposition, Nullable1 sendInvitationsMode, ServiceErrorHandling errorHandling)
at Microsoft.Exchange.WebServices.Data.Item.InternalCreate(FolderId parentFolderId, Nullable
1 messageDisposition, Nullable`1 sendInvitationsMode) at Microsoft.Exchange.WebServices.Data.Appointment.Save(FolderId destinationFolderId, SendInvitationsMode sendInvitationsMode) at HealthCheck360ExchangeLib.CallSlotRepository.CreateTestAppointment() in c:\Users\okane\Documents\Visual StudioProjects 2012 \HealthCheck360OutlookCallScheduleHelper\HealthCheck360ExchangeLib\CallSlotRepository.cs:line 70 at Hc360LibTests.UnitTest1.TestMeetingCreation() in c:\Users\okane\Documents\Visual Studio 2012\Projects\HealthCheck360OutlookCallSchedule1Hc360LibTests.UnitTest1.TestMeetingCreation()

Jak*_*sen 5

似乎无法保存继承的项目。

如果您深入查看 EWS 托管 API 的代码,您会发现序列化通过 ServiceObjectDefinitionAttribute 或方法 ServiceObject.GetXmlElementNameOverride 确定 XML 中的元素名称。该任命类的项目会沿用这反过来又继承ServiceObject。Appointment 类还具有 ServiceObjectDefinitionAttribute,并使用 XML 元素名称“CalendarItem”进行序列化。

因此,要使用从 Appointment 继承的类,您需要在您的类上使用 ServiceObjectDefintionAttribute,或者您必须覆盖 GetXmlElementNameOverride。不幸的是 ServiceObjectDefintionAttribute 和 GetXmlElementNameOverride 是内部的,所以没有办法做到这一点。

问题是为什么要使用继承的类?您是否希望 Exchange 能够保存您班级的属性?在这种情况下,您可能需要查看 ExtendedProperties

更新:

如果您想将扩展属性公开为您自己的类上的真实属性,您可以通过委托给 Appointment 对象来实现。它并不完美,但它是一种选择:

public class ExtendedAppointment
{
    Appointment _appointment;

    public ExtendedAppointment(Appointment appointment)
    {
        _appointment = appointment;
    }

    public Appointment Appointment { get { return _appointment; } }

    public object SomeExtendedProperty
    {
        get 
        { 
            return _appointment.ExtendedProperties[0].Value;
        }

        set
        {
            _appointment.ExtendedProperties[0].Value = value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)