Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get System.InvalidOperationException back from a WSDL call but not from the same call to another service?

Tags:

wcf

I have created service to get the country details information of various clients, but while hosting the service I am getting this exception. I am using basic http binding.

An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.InvalidOperationException: An exception was thrown in a call to a 
WSDL export extension:   
  System.ServiceModel.Description.DataContractSerializerOperationBehavior
  contract: http://tempuri.org/:IReferenceDataService ----> 
     System.Runtime.Serialization.InvalidDataContractException: 
     Type 'Pariwaar.BusinessObject.CountryBO' cannot be serialized. 
     Consider marking it with the DataContractAttribute attribute, 
     and marking all of its members you want serialized with the 
     DataMemberAttribute attribute. 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.DataContract.GetDataContract(RuntimeTypeHandle typeHandle, Type type, SerializationMode mode)
   at System.Runtime.Serialization.DataContractSet.GetDataContract(Type clrType)
   at System.Runtime.Serialization.DataContractSet.GetItemTypeDataContract(CollectionDataContract collectionContract)
   at System.Runtime.Serialization.DataContractSet.AddCollectionDataContract(CollectionDataContract collectionDataContract)
   at System.Runtime.Serialization.DataContractSet.Add(XmlQualifiedName name, DataContract dataContract)
   at System.Runtime.Serialization.DataContractSet.Add(Type type)
   at System.Runtime.Serialization.XsdDataContractExporter.Export(Type type)
   at System.ServiceModel.Description.MessageContractExporter.ExportType(Type type, String partName, String operationName, XmlSchemaType& xsdType)
   at System.ServiceModel.Description.DataContractSerializerMessageContractExporter.ExportBody(Int32 messageIndex, Object state)
   at System.ServiceModel.Description.MessageContractExporter.ExportMessage(Int32 messageIndex, Object state)
   at System.ServiceModel.Description.MessageContractExporter.ExportMessageContract()
   at System.ServiceModel.Description.DataContractSerializerOperationBehavior.System.ServiceModel.Description.IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext contractContext)
   at System.ServiceModel.Description.WsdlExporter.CallExtension(WsdlContractConversionContext contractContext, IWsdlExportExtension extension)
   --- End of inner ExceptionDetail stack trace ---
   at System.ServiceModel.Description.WsdlExporter.CallExtension(WsdlContractConversionContext contractContext, IWsdlExportExtension extension)
   at System.ServiceModel.Description.WsdlExporter.CallExportContract(WsdlContractConversionContext contractContext)
   at System.ServiceModel.Description.WsdlExporter.ExportContract(ContractDescription contract)
   at System.ServiceModel.Description.WsdlExporter.ExportEndpoint(ServiceEndpoint endpoint, XmlQualifiedName wsdlServiceQName)
   at System.ServiceModel.Description.WsdlExporter.ExportEndpoints(IEnumerable`1 endpoints, XmlQualifiedName wsdlServiceQName)
   at System.ServiceModel.Description.ServiceMetadataBehavior.MetadataExtensionInitializer.GenerateMetadata()
   at System.ServiceModel.Description.ServiceMetadataExtension.EnsureInitialized()
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.InitializationData.InitializeFrom(ServiceMetadataExtension extension)
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.GetInitData()
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.TryHandleDocumentationRequest(Message httpGetRequest, String[] queries, Message& replyMessage)
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.ProcessHttpRequest(Message httpGetRequest)
   at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.Get(Message message)
   at SyncInvokeGet(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

I have businessobject[datamember] in another project. I have referred its dll here.

You can view my class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Pariwaar.BusinessObject;
using Pariwaar.DataAccessLayer;

namespace Pariwaar.WCFServices.SVC
{
    // NOTE: If you change the class name "ReferenceDataService" here, you must also update the reference to "ReferenceDataService" in Web.config.
    public class ReferenceDataService : IReferenceDataService
    {
        ReferenceData objDAL = new ReferenceData();

        public List<CountryBO> GetCountry()
        { return objDAL.GetCountry(); }

        public List<StateBO> GetState(int CountryId)
        { return objDAL.GetState(CountryId); }

        public List<CityBO> GetCity(int StateId)
        { return objDAL.GetCity(StateId); }
    }
}

Why is this working fine with another WCF service, but giving me an error with another service?

like image 338
Radhi Avatar asked Dec 16 '09 12:12

Radhi


2 Answers

Well, the error is pretty clear:

System.Runtime.Serialization.InvalidDataContractException: Type 'Pariwaar.BusinessObject.CountryBO' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. See the Microsoft .NET Framework documentation for other supported types.

You're obviously using a datatype Pariwaar.BusinessObject.CountryBO as parameter or return value for one of your WCF service methods, but that class doesn't have a [DataContract] attribute on it.

See the MSDN docs on Using Data Contracts to learn about data contracts and how to make your objects useable by WCF. See this blog post - WCF Basics: Data Contracts for another view on the same topic.

All complex types (e.g. class) should be marked with [DataContract], all fields that you want to include in your WCF messages with [DataMember]:

[DataContract]
class Pariwaar.BusinessObject.CountryBO
{
   [DataMember]
   string CountryName { get; set; }

   [DataMember]
   string CountryCurrency { get; set; }

   [DataMember]
   string CountryISOCode { get; set; }

   ........
}

Marc

like image 83
marc_s Avatar answered Nov 06 '22 06:11

marc_s


Hi I encountered the same problem, It was because there was no default constructor on the object CountryBO.

like image 42
Ephy L Avatar answered Nov 06 '22 08:11

Ephy L