This is in relation to a previous question I asked:
I have a DLL defining a Transaction class. It is referenced by a WCF service library as well as a client application. I get errors stating that the service library cannot be hosted because it can't serialise the DLL class.
Here's the service code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using ServerLibrary.MarketService;
using SharedLibrary; // This is the DLL in question
namespace ServerLibrary
{
[ServiceContract]
public interface IService
{
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
[OperationContract]
bool ProcessTransaction(SharedLibrary.Transaction transaction);
}
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
}
Do I have to mark the Transaction class here with [attribute] headers?
[UPDATE]
Here's the error messages I get when I try to host this service:
System.Runtime.Serialization.InvalidDataContractException: Type 'SharedLibrary.Transaction' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types. at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(String message, Type type) at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(Int32 id, RuntimeTypeHandle typeHandle, Type type) at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(Int32 id, RuntimeTypeHandle typeHandle, Type type) at System.Runtime.Serialization.XsdDataContractExporter.GetSchemaTypeName(Type type) at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.ValidateDataContractType(Type type) at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.CreatePartInfo(MessagePartDescription part, OperationFormatStyle style, DataContractSerializerOperationBehavior serializerFactory) at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter.CreateMessageInfo(DataContractFormatAttribute dataContractFormatAttribute, MessageDescription messageDescription, DataContractSerializerOperationBehavior serializerFactory) at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter..ctor(OperationDescription description, DataContractFormatAttribute dataContractFormatAttribute, DataContractSerializerOperationBehavior serializerFactory) at System.ServiceModel.Description.DataContractSerializerOperationBehavior.GetFormatter(OperationDescription operation, Boolean& formatRequest, Boolean& formatReply, Boolean isProxy) at System.ServiceModel.Description.DataContractSerializerOperationBehavior.System.ServiceModel.Description.IOperationBehavior.ApplyDispatchBehavior(OperationDescription description, DispatchOperation dispatch) at System.ServiceModel.Description.DispatcherBuilder.BindOperations(ContractDescription contract, ClientRuntime proxy, DispatchRuntime dispatch) at System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost) at System.ServiceModel.ServiceHostBase.InitializeRuntime() at System.ServiceModel.ServiceHostBase.OnBeginOpen() at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open() at Microsoft.Tools.SvcHost.ServiceHostHelper.OpenService(ServiceInfo info)
As requested here is the DLL containing Transaction:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SharedLibrary
{
// Transaction class to encapsulate products and checkout data
public class Transaction
{
public int checkoutID;
public DateTime time;
public List<object> products; // Using object to avoid MarketService reference, remember to cast back!
public double totalPrice;
public bool complete;
public Transaction(int ID)
{
checkoutID = ID;
}
public void Start()
{
products = new List<object>();
complete = false;
}
public void Complete()
{
time = DateTime.Now;
complete = true;
}
}
}
Thanks.
Do I have to mark the Transaction class here with [attribute] headers?
No, you shouldn't have to, but it is recommended. See Using Data Contracts.
The problem is that you are passing derived objects in a List<object>
.
You have to tell the service what type objects to handle with a ServiceKnownType attribute:
[OperationContract]
[ServiceKnownType( typeof( MarketService.XXX ) )]
bool ProcessTransaction(SharedLibrary.Transaction transaction);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With