Исключение из службы WCF:форматер вызвал исключение при попытке десериализовать сообщение
Модуль форматирования выдал исключение при попытке десериализовать сообщение:
Произошла ошибка при попытке десериализации параметра http://tempuri.org/:GetPatientInsuranceInformationResult . Сообщение InnerException было " ошибка в строке 1 позиция 1604. Элемент "http://schemas.datacontract.org/2004/07/SubSonic:_currentValue ' содержит данные о 'http://schemas.datacontract.org/2004/07/System:DBNull договор' данных. То десериализатор не знает ни одного типа, который соответствует этому контракт. Добавьте тип, соответствующий 'DBNull' в список известных типы-например, с помощью атрибута KnownTypeAttribute или с помощью добавление его в список известных типов, передаваемых в Сериализатора datacontractserializer.". Пожалуйста, смотрите InnerException для получения более подробной информации
Моя служебная функция wcf
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;
}
Класс всегда порождается дозвуковым.и я написал частичный класс в бизнес-логике как следует
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;
}
}
}
}
.
2 ответа:
Моя служба WCF была собрана с использованием платформы 4.5, а мой клиент-потребитель был собран с использованием платформы 3.5. Из-за этого мастер добавления ссылок на службы не создавал атрибут класса для известных типов, которые были объявлены с помощью
[ServiceKnownType(typeof(System.DBNull))]
Итак, при десериализации клиент не получал систему.Тип DBNull. Мы должны добавить knowntypes в конфигурационный файл клиента.
Эта конфигурация, необходимая на стороне клиента, которая решила мою проблему:
<system.runtime.serialization> <dataContractSerializer> <declaredTypes> <add type="NameSpace.ServiceClientName.ClassNameForWhichKnownTypeIsToBeGiven, AssemblyName"> <knownType type="System.DBNull"></knownType> </add> </declaredTypes> </dataContractSerializer> </system.runtime.serialization>
Сообщение об ошибке в основном означает, что ваша коллекция содержит объект типа DBNull. ФОС десериализатор не имеет знания такого типа и, следовательно, вызывает исключение. Если вы добавите атрибут KnownTypeAttribute к вашему контракту данных и включите DBNull в его параметры, вы будете в порядке.
Примерно так:
[CollectionDataContract] [KnownType(typeof(DBNull))] public class YourList : ArrayList { }