WCF service Exception:The formatter threw an exception while trying to deserialize the message

user632299 picture user632299 · Aug 28, 2014 · Viewed 23.5k times · Source

The formatter threw an exception while trying to deserialize the message:

There was an error while trying to deserialize parameter http://tempuri.org/:GetPatientInsuranceInformationResult. The InnerException message was 'Error in line 1 position 1604. Element 'http://schemas.datacontract.org/2004/07/SubSonic:_currentValue' contains data of the 'http://schemas.datacontract.org/2004/07/System:DBNull' data contract. The deserializer has no knowledge of any type that maps to this contract. Add the type corresponding to 'DBNull' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details

my wcf service function

public PatientInsurance GetPatientInsuranceInformation(int PatientKey)
        {
            PatientInsurance col = new PatientInsurance();
            if (PatientKey > 0)
            {
                Query qry = new Query(PatientInsurance.Schema.TableName).WHERE(PatientInsurance.Columns.Deleted, false).AND(PatientInsurance.Columns.PatientKey, PatientKey);
                col.LoadAndCloseReader(qry.ExecuteReader());
            }
            return col;
        }

class always generated by subsonic.and i have written partial class in business logic as follows

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;


namespace PatientPortal.Model.Data
{
    [KnownType(typeof(System.DBNull))]
    [XmlInclude(typeof(DBNull))]
    [KnownType(typeof(PatientInsurance))]
    public partial class PatientInsurance
    {
        public string InsuranceTypeText
        {
            get
            {
                string insuranceTypeText = "";
                //if (!string.IsNullOrEmpty(Convert.ToString(this.InsuranceType)))
                //{
                //    int InsuranceType = Convert.ToInt32(this.InsuranceType);
                //    switch (InsuranceType)
                //    {
                //        case 1:
                //            insuranceTypeText = "Primary Insurance";
                //            break;
                //        case 2:
                //            insuranceTypeText = "Secondary Insurance";
                //            break;
                //        case 3:
                //            insuranceTypeText = "Tertiary Insurance";
                //            break;
                //    }
                //}
                return insuranceTypeText;
            }
        }

        public string PrimPolicyHolderNameDisplay
        {
            get
            {
                string primPolicyHolderNameDisplay = "display:none;";
                if (!string.IsNullOrEmpty(Convert.ToString(this.PrimRelationship)))
                {
                    primPolicyHolderNameDisplay = (this.PrimRelationship == "Self") ? "display:none;" : "";
                }
                return primPolicyHolderNameDisplay;
            }
        }

        public string SecPolicyHolderNameDisplay
        {
            get
            {
                string secPolicyHolderNameDisplay = "display:none;";
                if (!string.IsNullOrEmpty(Convert.ToString(this.SecRelationship)))
                {
                    secPolicyHolderNameDisplay = (this.SecRelationship == "Self") ? "display:none;" : "";
                }
                return secPolicyHolderNameDisplay;
            }
        }

        public string TerPolicyHolderNameDisplay
        {
            get
            {
                string terPolicyHolderNameDisplay = "display:none;";
                if (!string.IsNullOrEmpty(Convert.ToString(this.TerRelationship)))
                {
                    terPolicyHolderNameDisplay = (this.TerRelationship == "Self") ? "display:none;" : "";
                }
                return terPolicyHolderNameDisplay;
            }
        }
    }
}

.

Answer

user632299 picture user632299 · Aug 31, 2014

My WCF service was build using framework 4.5 and my consuming client was build using framework 3.5. Due to this Add Service Reference wizard was not generating Class attribute for KnownTypes which were declared using

 [ServiceKnownType(typeof(System.DBNull))] 

So, when deserializing client was not getting System.DBNull type. We have to add knowntypes in clients config file.

This Configuration needed at client side which solved my problem:

<system.runtime.serialization>
        <dataContractSerializer>    
            <declaredTypes>
                <add type="NameSpace.ServiceClientName.ClassNameForWhichKnownTypeIsToBeGiven, AssemblyName">
                    <knownType  type="System.DBNull"></knownType>
                </add>
             </declaredTypes>
        </dataContractSerializer>
</system.runtime.serialization>