1

I'm getting an exception when initializing an XMLSerializer and passing it an instance of Appointment (from the EWS API):

Microsoft.Exchange.WebServices.Data.Appointment cannot be serialized because it does not have a parameterless constructor.

Here is my code:

private static string FindAppointmentsAsXmlString(CalendarView calendar, ExchangeService serv)
{
    FindItemsResults<Appointment> appointments = serv.FindAppointments(
        WellKnownFolderName.Calendar, calendar);
    List<Appointment> appointmentsList = appointments.ToList();

    var serializer = new XmlSerializer(appointmentsList.GetType());
    var writer = new StringWriter();

    try
    {
        serializer.Serialize(writer, appointmentsList);
        Console.WriteLine(writer.GetStringBuilder().ToString());
        Console.ReadLine();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
        Console.ReadLine();
    }

    return writer.GetStringBuilder().ToString(); 
}
LKB
  • 1,020
  • 5
  • 22
  • 46
  • 1
    @GrantWinney I don't get how that helps me, unless you can provide some insight? – LKB May 30 '13 at 23:43
  • ...And I just ran my application again and it's "parameterless". My fault! Ah! – LKB May 31 '13 at 00:06

2 Answers2

1

The reason I linked to the post in my comment above (since deleted) is that it states that:

During an object's de-serialization, the class responsible for de-serializing an object creates an instance of the serialized class and then proceeds to populate the serialized fields and properties only after acquiring an instance to populate.

You can see from the documentation of the Appointment constructor that Appointment requires an instance of ExchangeService in the constructor... there is no parameterless constructor, hence the error.

I don't know about all the inner-workings of the serialization process, but hopefully this gives you a reason for the error at least.

Normally, if it were your own class, you should just be able to add an additional (parameterless) constructor, but I'm not sure what you do in this case. There may very well be another way to successfully serialize the Appointment class, but I'm not sure.

You could try extending the Appointment class, providing a parameterless constructor in there, and then serialize that using XML. I'm not sure it'll work, but maybe someone else can provide a more definite answer.

public class MyAppointment : Appointment
{
    public MyAppointment() { }
}

If I find anything else on it, I'll update this.

Community
  • 1
  • 1
Grant Winney
  • 65,241
  • 13
  • 115
  • 165
  • Thanks Grant, very helpful! I'm Serializing the Appointment object as I'm writing the contents to an XML file, is there an alternative way, avoiding this exception, to write the object's contents to an XML file? – LKB May 31 '13 at 00:21
  • Thanks for your help @GrantWinney, I did have an alternative thought - run through a List of type Appointments, convert each node to String, then Serialize? Also when implementing a class which extends Appointment, the result is: "'Microsoft.Exchange...Appointment' does not contain a constructor that takes 0 arguments" – LKB May 31 '13 at 00:50
  • I'll give it a go, I don't see how that wouldn't work. Cheers! – LKB May 31 '13 at 00:59
1

if you use AutoMapper, either get it by Nuget or https://github.com/AutoMapper/AutoMapper if you do :-

namespace DTO
    {        
        public class CalendarAppointment : Appointment
        {
            public CalendarAppointment() : base( /* any parameters to construct the base appointment, doesn't matter /* )
            {
            }
        }
}

then you can do

private static string FindAppointmentsAsXmlString(CalendarView calendar, ExchangeService serv)
        {
            FindItemsResults<Appointment> appointments = serv.FindAppointments(
                WellKnownFolderName.Calendar, calendar);

            Mapper.CreateMap<Appointment, DTO.CalendarAppointment>();

            var list = appointments.Select(Mapper.Map<DTO.CalendarAppointment>).ToList();
            var serializer = new XmlSerializer(list.GetType());
            var writer = new StringWriter();

            try
            {
                serializer.Serialize(writer, list);
                Console.WriteLine(writer.GetStringBuilder().ToString());
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                Console.ReadLine();
            }

            return writer.GetStringBuilder().ToString();
        }
Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156