Follow on question from Error with explicit conversion when using CollectAs<>
Code from WebMethod
return client.Cypher
.Match("(person:Person)")
.Where((Person person) => person.Email == username)
.OptionalMatch("(person)-[:SPEAKS]-(language:Language)")
.OptionalMatch("(person)-[:CURRENT_LOCATION]-(country:Country)"
.Return((person, language, country) => new ProfileObject
{
Person = person.As<Person>(),
Language = language.CollectAs<Language>(),
Country = country.CollectAs<Country>()
}).Results.ToList();
Code from Country Class:
public class Language
{
public string Name { get; set; }
}
New code from ProfileObject Class:
public class ProfileObject
{
public Person Person { get; set; }
public IEnumerable<Node<Language>> Language { get; set; }
public IEnumerable<Node<Country>> Country { get; set; }
}
This error only happens when I set ProfileObject to return IEnumerable>, if I return it to just
public Country Country {get; set;}
then it works (but I obviously get duplicated Person entries for each Country object returned.
Anyone able to show me a solution to this problem that doesn't involve me ripping all of the code out and starting again?
Update:
[InvalidOperationException: Neo4jClient.Node`1[Graph.Language] cannot be serialized because it does not have a parameterless constructor.]
[InvalidOperationException: Cannot serialize member 'Graph.ProfileObject.Language' of type 'System.Collections.Generic.List
1[[Neo4jClient.Node
1[[Graph.Language, Graph, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], Neo4jClient, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]', see inner exception for more details.]
System.Xml.Serialization.StructModel.CheckSupportedMember(TypeDesc typeDesc, MemberInfo member, Type type) +5451673
System.Xml.Serialization.StructModel.CheckSupportedMember(TypeDesc typeDesc, MemberInfo member, Type type) +69
System.Xml.Serialization.StructModel.GetPropertyModel(PropertyInfo propertyInfo) +125
System.Xml.Serialization.StructModel.GetFieldModel(MemberInfo memberInfo) +89
System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter) +618
System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter) +378
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter) +1799[InvalidOperationException: There was an error reflecting type 'Graph.ProfileObject'.]
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter) +1917
System.Xml.Serialization.XmlReflectionImporter.CreateArrayElementsFromAttributes(ArrayMapping arrayMapping, XmlArrayItemAttributes attributes, Type arrayElementType, String arrayElementNs, RecursionLimiter limiter) +263
System.Xml.Serialization.XmlReflectionImporter.ImportArrayLikeMapping(ArrayModel model, String ns, RecursionLimiter limiter) +264
System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +5456308
System.Xml.Serialization.XmlReflectionImporter.ImportMemberMapping(XmlReflectionMember xmlReflectionMember, String ns, XmlReflectionMember[] xmlReflectionMembers, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +852
System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, String ns, Boolean hasWrapperElement, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +286[InvalidOperationException: There was an error reflecting 'MyResult'.]
System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, String ns, Boolean hasWrapperElement, Boolean rpc, Boolean openModel, RecursionLimiter limiter) +979
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) +240
System.Web.Services.Protocols.SoapReflector.ReflectMethod(LogicalMethodInfo methodInfo, Boolean client, XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, String defaultNs) +2893[InvalidOperationException: Method ProfileServices.My can not be reflected.]
System.Web.Services.Protocols.SoapReflector.ReflectMethod(LogicalMethodInfo methodInfo, Boolean client, XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, String defaultNs) +6173
System.Web.Services.Description.SoapProtocolReflector.ReflectMethod() +137
System.Web.Services.Description.ProtocolReflector.ReflectBinding(ReflectedBinding reflectedBinding) +1776
System.Web.Services.Description.ProtocolReflector.Reflect() +641
System.Web.Services.Description.ServiceDescriptionReflector.ReflectInternal(ProtocolReflector[] reflectors) +685
System.Web.Services.Description.ServiceDescriptionReflector.Reflect(Type type, String url) +118
System.Web.Services.Protocols.DocumentationServerType..ctor(Type type, String uri, Boolean excludeSchemeHostPortFromCachingKey) +230
System.Web.Services.Protocols.DocumentationServerProtocol.Initialize() +434
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) +320
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) +374
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) +48
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
Best Answer
By default, asp.net uses
DataContractSerializer
to serialize to XML, however the error message"Cannot serialize member <x> because it is an interface"
is generated byXmlSerializer
, so apparently you have switched to that.You could consider switching back to
DataContractSerializer
as specified here, which can serialize properties of typeIEnumerable<T>
as long as the underlying typeT
can be serialized.Alternatively, if you don't want to do that, you could modify your
ProfileObject
class to return proxy arrays for serialization without changing your underlying design:Update
XmlSerializer
will only serialize properties with publicget
andset
methods. SinceNode.Data
is get-only, it can't be serialized byXmlSerializer
.Since you only need to serialize the data and not the
Node<TData>
, and never need to deserialize, you can use linq to return transform your enumerable of nodes to an array of data for serialization as follows: