I am getting the following error when trying to return a Questionnaire object to the client. I added the KnowType[typeof(...)] in the Data Contract as suggested, but it still doesn't work. Not knowing which type is unknown to the Serializer, I just threw in all classes that are in the EF model. Can someone help? Thanks.
Here is the Service Contract
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; }
}
}
Here is the 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;
}
}
}
This is the exception in the Windows Application Log.
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>