Je reçois l'erreur suivante lorsque j'essaie de renvoyer un objet Questionnaire au client. J'ai ajouté le KnowType [typeof (...)] dans le contrat de données comme suggéré, mais cela ne fonctionne toujours pas. Ne sachant pas quel type est inconnu au Serializer, j'ai juste jeté dans toutes les classes qui sont dans le modèle EF. Quelqu'un peut-il aider? Merci.WCF DataContractSerializer
Voici le contrat de service
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using QuestionnaireWcfServiceApp.Models;
namespace QuestionnaireWcfService
{
[ServiceContract]
public interface IQuestionnaireService
{
[OperationContract]
QuestionnaireContract GetQuestionnaire(string questionnaireName);
[OperationContract]
QuestionChain LoadQuestion(int questionnaireID, int? questionID, int? userResponse);
}
[DataContract]
[KnownType(typeof(Questionnaire))]
[KnownType(typeof(Question))]
[KnownType(typeof(Choice))]
[KnownType(typeof(Decision))]
[KnownType(typeof(QuestionFlow))]
public class QuestionChain
{
[DataMember]
public Question Question { get; set; }
[DataMember]
public int? Decision {get;set;}
}
[DataContract]
[KnownType(typeof(Questionnaire))]
[KnownType(typeof(Question))]
[KnownType(typeof(Choice))]
[KnownType(typeof(Decision))]
[KnownType(typeof(QuestionFlow))]
public class QuestionnaireContract
{
[DataMember]
public Questionnaire Questionnaire { get; set; }
}
}
Voici le Service.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using QuestionnaireWcfServiceApp.Models;
namespace QuestionnaireWcfService
{
public class QuestionnaireService : IQuestionnaireService
{
QuestionnaireWcfServiceApp.Models.QuestionnaireEntities db = new QuestionnaireEntities();
public QuestionnaireContract GetQuestionnaire(string questionnaireName)
{
QuestionnaireContract questionnaireContract = new QuestionnaireContract();
if (!string.IsNullOrEmpty(questionnaireName))
{
Questionnaire thisQuestionnaire = (from q in db.Questionnaires where q.Name.Equals(questionnaireName) select q).FirstOrDefault();
if (thisQuestionnaire == null)
throw new ArgumentNullException("Questionnaire ID is not found.");
else
{
questionnaireContract.Questionnaire = thisQuestionnaire;
return questionnaireContract;
}
}
else
throw new ArgumentException("Questionnaire name is not specified.");
}
public QuestionChain LoadQuestion(int questionnaireID, int? currentQuestionID, int? userResponse)
{
QuestionChain qc = new QuestionChain();
QuestionFlow thisFlow = null;
Question nextQuestion = null;
Questionnaire thisQuestionnaire = (from q in db.Questionnaires where q.QuestionnaireId == questionnaireID select q).FirstOrDefault();
if (thisQuestionnaire == null)
throw new ArgumentNullException("Questionnaire ID is not found"); //InvalidOperationException;
if (currentQuestionID.HasValue)
{
//QuestionID should never be changed after setup. Change the QuestionText around the QuestionID
Question thisQuestion = thisQuestionnaire.Questions.Where(q => q.PKey.Equals(currentQuestionID)).FirstOrDefault();
if (thisQuestion == null)
throw new ArgumentNullException("Question ID is not found");
else
{
if (userResponse.HasValue)
{
thisFlow = thisQuestion.QuestionFlows.First(f => f.QuestionId.Equals(currentQuestionID) && f.ChoiceId.Equals(userResponse));
if (thisFlow.Question1 != null)
{
nextQuestion = thisFlow.Question1;
qc.Question = nextQuestion;
}
else
{
qc.Question = null;
qc.Decision = thisFlow.Decision.Value;
}
}
else
{
//can't happen. when reaches here, a userResponse must not be null
}
}
}
else
{
//default to question 1
nextQuestion = thisQuestionnaire.Questions.First(q => q.QuestionId.Equals(1));
if (nextQuestion == null)
throw new ArgumentNullException("Question ID");
else
qc.Question = nextQuestion;
}
return qc;
}
}
}
Ceci est l'exception dans le journal des applications Windows.
Exception: System.ServiceModel.CommunicationException: There was an error while trying to serialize parameter http://tempuri.org/:GetQuestionnaireResult. The InnerException message was 'Type System.Data.Entity.DynamicProxies.Questionnaire_EF00247BEFB9F733C947A4C3E57FD12709E91510AC0DA534D137ED75FCCAC342'
with data contract name 'Questionnaire_EF00247BEFB9F733C947A4C3E57FD12709E91510AC0DA534D137ED75FCCAC342:
http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies'
is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details. ---> System.Runtime.Serialization.SerializationException: Type 'System.Data.Entity.DynamicProxies.Questionnaire_EF00247BEFB9F733C947A4C3E57FD12709E91510AC0DA534D137ED75FCCAC342' with data contract name 'Questionnaire_EF00247BEFB9F733C947A4C3E57FD12709E91510AC0DA534D137ED75FCCAC342:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle originalDeclaredTypeHandle, Type graphType)
at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.WriteObject(XmlDictionaryWriter writer, Object graph)
at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameterPart(XmlDictionaryWriter writer, PartInfo part, Object graph)
--- End of inner exception stack trace ---
at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameterPart(XmlDictionaryWriter writer, PartInfo part, Object graph)
at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameter(XmlDictionaryWriter writer, PartInfo part, Object graph)
at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, String action, MessageDescription messageDescription, Object returnValue, Object[] parameters, Boolean isRequest)
at System.ServiceModel.Dispatcher.OperationFormatter.SerializeBodyContents(XmlDictionaryWriter writer, MessageVersion version, Object[] parameters, Object returnValue, Boolean isRequest)
at System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage.OperationFormatterBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer)
at System.ServiceModel.Channels.BodyWriterMessage.OnBodyToString(XmlDictionaryWriter writer)
at System.ServiceModel.Channels.Message.ToString(XmlDictionaryWriter writer)
at System.ServiceModel.Diagnostics.MessageLogTraceRecord.WriteTo(XmlWriter writer)
at System.ServiceModel.Diagnostics.MessageLogger.LogInternal(MessageLogTraceRecord record)
at System.ServiceModel.Diagnostics.MessageLogger.LogMessageImpl(Message& message, XmlReader reader, MessageLoggingSource source)
at System.ServiceModel.Diagnostics.MessageLogger.LogMessage(Message& message, XmlReader reader, MessageLoggingSource source)
Process Name: WebDev.WebServer40
Process ID: 11620
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="System.ServiceModel 4.0.0.0" />
<EventID Qualifiers="49154">5</EventID>
<Level>2</Level>
<Task>7</Task>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2012-10-18T07:32:11.000000000Z" />
<EventRecordID>36499</EventRecordID>
<Channel>Application</Channel>
<Computer>Jon-PC</Computer>
<Security UserID="S-1-5-21-334737869-2079735299-2176000493-1000" />
</System>
<EventData>
<Data>System.ServiceModel.CommunicationException: There was an error while trying to serialize parameter http://tempuri.org/:GetQuestionnaireResult. The InnerException message was 'Type 'System.Data.Entity.DynamicProxies.Questionnaire_EF00247BEFB9F733C947A4C3E57FD12709E91510AC0DA534D137ED75FCCAC342' with data contract name 'Questionnaire_EF00247BEFB9F733C947A4C3E57FD12709E91510AC0DA534D137ED75FCCAC342:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details. ---> System.Runtime.Serialization.SerializationException: Type 'System.Data.Entity.DynamicProxies.Questionnaire_EF00247BEFB9F733C947A4C3E57FD12709E91510AC0DA534D137ED75FCCAC342' with data contract name 'Questionnaire_EF00247BEFB9F733C947A4C3E57FD12709E91510AC0DA534D137ED75FCCAC342:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle originalDeclaredTypeHandle, Type graphType)
at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.WriteObject(XmlDictionaryWriter writer, Object graph)
at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameterPart(XmlDictionaryWriter writer, PartInfo part, Object graph)
--- End of inner exception stack trace ---
at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameterPart(XmlDictionaryWriter writer, PartInfo part, Object graph)
at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeParameter(XmlDictionaryWriter writer, PartInfo part, Object graph)
at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.SerializeBody(XmlDictionaryWriter writer, MessageVersion version, String action, MessageDescription messageDescription, Object returnValue, Object[] parameters, Boolean isRequest)
at System.ServiceModel.Dispatcher.OperationFormatter.SerializeBodyContents(XmlDictionaryWriter writer, MessageVersion version, Object[] parameters, Object returnValue, Boolean isRequest)
at System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage.OperationFormatterBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer)
at System.ServiceModel.Channels.BodyWriterMessage.OnBodyToString(XmlDictionaryWriter writer)
at System.ServiceModel.Channels.Message.ToString(XmlDictionaryWriter writer)
at System.ServiceModel.Diagnostics.MessageLogTraceRecord.WriteTo(XmlWriter writer)
at System.ServiceModel.Diagnostics.MessageLogger.LogInternal(MessageLogTraceRecord record)
at System.ServiceModel.Diagnostics.MessageLogger.LogMessageImpl(Message& message, XmlReader reader, MessageLoggingSource source)
at System.ServiceModel.Diagnostics.MessageLogger.LogMessage(Message& message, XmlReader reader, MessageLoggingSource source)</Data>
<Data>WebDev.WebServer40</Data>
<Data>11620</Data>
</EventData>
</Event>
Peut-être que c'est juste la configuration de mon navigateur (les images postées semblent être filtrées), mais je ne vois aucun texte d'exception. Pourriez-vous s'il vous plaît poster l'exception? –
J'ai édité et reformaté le message. L'exception est plutôt longue. Vous devez utiliser les barres de défilement vertical et horizontal pour afficher le texte intégral. Merci. – user266909
Il ressemble à un objet paresseusement chargé par EF qui a créé un proxy dynamique à l'exécution qui ne peut pas être sérialisé. Vous devriez charger toutes les associations avec impatience. Et soyez prudent car si vous avez des dépendances circulaires dans votre hiérarchie d'objets, il ne peut pas non plus être sérialisé. Le meilleur moyen consiste à utiliser des objets de transfert de données et à ne pas exposer vos entités EF dans le contrat de service. –