对象无法序列化,因为它没有无参数构造函数
Object cannot be serialized because it does not have a parameterless constructor
我正在尝试编写一个使用 EWS API (2.2) 查询 Exchange 的 Web 服务。我可以使用 Console.Write
获取数据,但我想向我的 SOAP Web 服务的用户提供数据。
我正在使用以下代码:
public class GetAppointments
{
public static List<Appointment> GetAppointment()
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
service.UseDefaultCredentials = true;
//service.Credentials = new WebCredentials("username", "password", "domain");
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
service.AutodiscoverUrl("service@organisation.com", RedirectionUrlValidationCallback);
//service.ImpersonatedUserId = new ImpersonatedUserID(ConnectingIdType.SmtpAddres, "user@domain");
// Initialize values for the start and end times, and the number of appointments to retrieve.
DateTime startDate = DateTime.Now;
DateTime endDate = startDate.AddDays(30);
//const int NUM_APPTS = 5;
// Initialize the calendar folder object with only the folder ID.
CalendarFolder calendar = CalendarFolder.Bind(service, WellKnownFolderName.Calendar, new PropertySet());
// Set the start and end time and number of appointments to retrieve.
// CalendarView cView = new CalendarView(startDate, endDate, NUM_APPTS);
ItemView view = new ItemView(100);
// Set the mailbox to query
String MailBoxToAccess = "myname@organisation.com";
FolderId CalendarFolderId = new FolderId(WellKnownFolderName.Calendar, MailBoxToAccess);
// Limit the properties returned to the appointment's subject, start time, and end time.
view.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End);
// Retrieve a collection of appointments by using the calendar view.
//FindItemsResults<Appointment> appointments = service.FindAppointments(CalendarFolderId, cView);
SearchFilter subjectFilter = new SearchFilter.IsEqualTo(AppointmentSchema.Subject, "TEST");
FindItemsResults<Item> appointments = service.FindItems(CalendarFolderId, subjectFilter, view);
List<Appointment> AppointmentResult = new List<Appointment>();
if (appointments.Items.Count > 0)
{
foreach (Appointment a in appointments)
{
var ApptResult = new Appointment(service)
{
Subject = a.Subject,
Start = a.Start,
End = a.End,
};
AppointmentResult.Add(ApptResult);
}
}
else
{
return null;
}
return AppointmentResult;
}
private static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
// The default for the validation callback is to reject the URL.
bool result = false;
Uri redirectionUri = new Uri(redirectionUrl);
// Validate the contents of the redirection URL. In this simple validation
// callback, the redirection URL is considered valid if it is using HTTPS
// to encrypt the authentication credentials.
if (redirectionUri.Scheme == "https")
{
result = true;
}
return result;
}
}
当我尝试 运行 时出现以下错误:
*Microsoft.Exchange.WebServices.Data.Appointment cannot be serialized because it does not have a parameterless constructor.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: Microsoft.Exchange.WebServices.Data.Appointment cannot be serialized because it does not have a parameterless constructor.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[InvalidOperationException: Microsoft.Exchange.WebServices.Data.Appointment cannot be serialized because it does not have a parameterless constructor.]
System.Xml.Serialization.TypeDesc.CheckSupported() +5651485
System.Xml.Serialization.TypeDesc.CheckSupported() +45
System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo source, Boolean directReference, Boolean throwOnError) +172
System.Xml.Serialization.XmlReflectionImporter.ImportMemberMapping(XmlReflectionMember xmlReflectionMember, String ns, XmlReflectionMember[] xmlReflectionMembers, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +73
System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, String ns, Boolean hasWrapperElement, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +286
[InvalidOperationException: There was an error reflecting 'GetAppointmentResult'.]
System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, String ns, Boolean hasWrapperElement, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +899
System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(String elementName, String ns, XmlReflectionMember[] members, Boolean hasWrapperElement, Boolean rpc, Boolean openModel, XmlMappingAccess access) +133
System.Web.Services.Protocols.SoapReflector.ImportMembersMapping(XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, Boolean serviceDefaultIsEncoded, Boolean rpc, SoapBindingUse use, SoapParameterStyle paramStyle, String elementName, String elementNamespace, Boolean nsIsDefault, XmlReflectionMember[] members, Boolean validate, Boolean openModel, String key, Boolean writeAccess) +233
System.Web.Services.Protocols.SoapReflector.ReflectMethod(LogicalMethodInfo methodInfo, Boolean client, XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, String defaultNs) +2862
[InvalidOperationException: Method WebService.GetAppointment can not be reflected.]
System.Web.Services.Protocols.SoapReflector.ReflectMethod(LogicalMethodInfo methodInfo, Boolean client, XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, String defaultNs) +6262
System.Web.Services.Description.SoapProtocolReflector.ReflectMethod() +137
System.Web.Services.Description.ProtocolReflector.ReflectBinding(ReflectedBinding reflectedBinding) +1577
System.Web.Services.Description.ProtocolReflector.Reflect() +641
System.Web.Services.Description.ServiceDescriptionReflector.ReflectInternal(ProtocolReflector[] reflectors) +559
System.Web.Services.Description.ServiceDescriptionReflector.Reflect(Type type, String url) +109
System.Web.Services.Protocols.DocumentationServerType..ctor(Type type, String uri, Boolean excludeSchemeHostPortFromCachingKey) +230
System.Web.Services.Protocols.DocumentationServerProtocol.Initialize() +472
System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing) +122
[InvalidOperationException: Unable to handle request.]
System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing) +325
System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type, HttpContext context, HttpRequest request, HttpResponse response) +171
[InvalidOperationException: Failed to handle request.]
System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type, HttpContext context, HttpRequest request, HttpResponse response) +346
System.Web.Services.Protocols.WebServiceHandlerFactory.GetHandler(HttpContext context, String verb, String url, String filePath) +209
System.Web.Script.Services.ScriptHandlerFactory.GetHandler(HttpContext context, String requestType, String url, String pathTranslated) +47
System.Web.HttpApplication.MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, Boolean useAppConfig) +226
System.Web.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +145
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155*
我不确定我需要做什么来克服这个问题,或者我是否以正确的方式解决这个问题。我乐于接受建议。
通过 API 发送第三方对象并不总是一个好主意,在这种情况下看起来确实是这样。您需要考虑 API 的消费者需要在另一端重建 class,如果它没有无参数构造函数,那是不可能的。
相反,最好创建您自己的模型并从中发送您需要的值。例如,假设 Appointment
class 看起来像这样(我知道它不是,但它作为一个例子):
public class Appointment
{
public string Title { get; set; }
public string Body { get; set; }
public DateTime MeetingTime { get; set; }
}
然后创建您自己的 class 模仿 Appointment
:
public class AppointmentModel
{
public string Title { get; set; }
public string Body { get; set; }
public DateTime MeetingTime { get; set; }
}
现在不再 return 使用 Appointment
,return 您自己的模型:
public static List<Appointment> GetAppointment()
{
//snip
List<Appointment> appointments = GetAllAppointments()
//Use some Linq to project into your own model
return appointments
.Select(a => new AppointmentModel
{
Title = a.Title,
Body = a.Body,
MeetingTime = a.MeetingTime
})
.ToList();
}
我正在尝试编写一个使用 EWS API (2.2) 查询 Exchange 的 Web 服务。我可以使用 Console.Write
获取数据,但我想向我的 SOAP Web 服务的用户提供数据。
我正在使用以下代码:
public class GetAppointments
{
public static List<Appointment> GetAppointment()
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
service.UseDefaultCredentials = true;
//service.Credentials = new WebCredentials("username", "password", "domain");
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
service.AutodiscoverUrl("service@organisation.com", RedirectionUrlValidationCallback);
//service.ImpersonatedUserId = new ImpersonatedUserID(ConnectingIdType.SmtpAddres, "user@domain");
// Initialize values for the start and end times, and the number of appointments to retrieve.
DateTime startDate = DateTime.Now;
DateTime endDate = startDate.AddDays(30);
//const int NUM_APPTS = 5;
// Initialize the calendar folder object with only the folder ID.
CalendarFolder calendar = CalendarFolder.Bind(service, WellKnownFolderName.Calendar, new PropertySet());
// Set the start and end time and number of appointments to retrieve.
// CalendarView cView = new CalendarView(startDate, endDate, NUM_APPTS);
ItemView view = new ItemView(100);
// Set the mailbox to query
String MailBoxToAccess = "myname@organisation.com";
FolderId CalendarFolderId = new FolderId(WellKnownFolderName.Calendar, MailBoxToAccess);
// Limit the properties returned to the appointment's subject, start time, and end time.
view.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End);
// Retrieve a collection of appointments by using the calendar view.
//FindItemsResults<Appointment> appointments = service.FindAppointments(CalendarFolderId, cView);
SearchFilter subjectFilter = new SearchFilter.IsEqualTo(AppointmentSchema.Subject, "TEST");
FindItemsResults<Item> appointments = service.FindItems(CalendarFolderId, subjectFilter, view);
List<Appointment> AppointmentResult = new List<Appointment>();
if (appointments.Items.Count > 0)
{
foreach (Appointment a in appointments)
{
var ApptResult = new Appointment(service)
{
Subject = a.Subject,
Start = a.Start,
End = a.End,
};
AppointmentResult.Add(ApptResult);
}
}
else
{
return null;
}
return AppointmentResult;
}
private static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
// The default for the validation callback is to reject the URL.
bool result = false;
Uri redirectionUri = new Uri(redirectionUrl);
// Validate the contents of the redirection URL. In this simple validation
// callback, the redirection URL is considered valid if it is using HTTPS
// to encrypt the authentication credentials.
if (redirectionUri.Scheme == "https")
{
result = true;
}
return result;
}
}
当我尝试 运行 时出现以下错误:
*Microsoft.Exchange.WebServices.Data.Appointment cannot be serialized because it does not have a parameterless constructor.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: Microsoft.Exchange.WebServices.Data.Appointment cannot be serialized because it does not have a parameterless constructor.
Source Error: An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[InvalidOperationException: Microsoft.Exchange.WebServices.Data.Appointment cannot be serialized because it does not have a parameterless constructor.]
System.Xml.Serialization.TypeDesc.CheckSupported() +5651485
System.Xml.Serialization.TypeDesc.CheckSupported() +45
System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo source, Boolean directReference, Boolean throwOnError) +172
System.Xml.Serialization.XmlReflectionImporter.ImportMemberMapping(XmlReflectionMember xmlReflectionMember, String ns, XmlReflectionMember[] xmlReflectionMembers, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +73
System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, String ns, Boolean hasWrapperElement, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +286
[InvalidOperationException: There was an error reflecting 'GetAppointmentResult'.]
System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, String ns, Boolean hasWrapperElement, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +899
System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(String elementName, String ns, XmlReflectionMember[] members, Boolean hasWrapperElement, Boolean rpc, Boolean openModel, XmlMappingAccess access) +133
System.Web.Services.Protocols.SoapReflector.ImportMembersMapping(XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, Boolean serviceDefaultIsEncoded, Boolean rpc, SoapBindingUse use, SoapParameterStyle paramStyle, String elementName, String elementNamespace, Boolean nsIsDefault, XmlReflectionMember[] members, Boolean validate, Boolean openModel, String key, Boolean writeAccess) +233
System.Web.Services.Protocols.SoapReflector.ReflectMethod(LogicalMethodInfo methodInfo, Boolean client, XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, String defaultNs) +2862
[InvalidOperationException: Method WebService.GetAppointment can not be reflected.]
System.Web.Services.Protocols.SoapReflector.ReflectMethod(LogicalMethodInfo methodInfo, Boolean client, XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, String defaultNs) +6262
System.Web.Services.Description.SoapProtocolReflector.ReflectMethod() +137
System.Web.Services.Description.ProtocolReflector.ReflectBinding(ReflectedBinding reflectedBinding) +1577
System.Web.Services.Description.ProtocolReflector.Reflect() +641
System.Web.Services.Description.ServiceDescriptionReflector.ReflectInternal(ProtocolReflector[] reflectors) +559
System.Web.Services.Description.ServiceDescriptionReflector.Reflect(Type type, String url) +109
System.Web.Services.Protocols.DocumentationServerType..ctor(Type type, String uri, Boolean excludeSchemeHostPortFromCachingKey) +230
System.Web.Services.Protocols.DocumentationServerProtocol.Initialize() +472
System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing) +122
[InvalidOperationException: Unable to handle request.]
System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing) +325
System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type, HttpContext context, HttpRequest request, HttpResponse response) +171
[InvalidOperationException: Failed to handle request.]
System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type, HttpContext context, HttpRequest request, HttpResponse response) +346
System.Web.Services.Protocols.WebServiceHandlerFactory.GetHandler(HttpContext context, String verb, String url, String filePath) +209
System.Web.Script.Services.ScriptHandlerFactory.GetHandler(HttpContext context, String requestType, String url, String pathTranslated) +47
System.Web.HttpApplication.MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, Boolean useAppConfig) +226
System.Web.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +145
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155*
我不确定我需要做什么来克服这个问题,或者我是否以正确的方式解决这个问题。我乐于接受建议。
通过 API 发送第三方对象并不总是一个好主意,在这种情况下看起来确实是这样。您需要考虑 API 的消费者需要在另一端重建 class,如果它没有无参数构造函数,那是不可能的。
相反,最好创建您自己的模型并从中发送您需要的值。例如,假设 Appointment
class 看起来像这样(我知道它不是,但它作为一个例子):
public class Appointment
{
public string Title { get; set; }
public string Body { get; set; }
public DateTime MeetingTime { get; set; }
}
然后创建您自己的 class 模仿 Appointment
:
public class AppointmentModel
{
public string Title { get; set; }
public string Body { get; set; }
public DateTime MeetingTime { get; set; }
}
现在不再 return 使用 Appointment
,return 您自己的模型:
public static List<Appointment> GetAppointment()
{
//snip
List<Appointment> appointments = GetAllAppointments()
//Use some Linq to project into your own model
return appointments
.Select(a => new AppointmentModel
{
Title = a.Title,
Body = a.Body,
MeetingTime = a.MeetingTime
})
.ToList();
}