WCF의 직렬화 및 비 직렬화에 관해서는 또 다른 "신비"에 직면 해 있습니다. 자세한 내용을 안내하겠습니다. IDataContractSurrogate, NHibernate 및 nulling 프록시 객체
- 우리는 presisted 객체 우리가 (TCP 주최)를 WCF 서비스에서 반환하는 (NHibernate에)가 있습니다.
우리는 속성/컬렉션 검사 NHibernate에 프록시하고 경우 DataContractSurrogate이 너무 다음 중 하나를 수행하는 경우 :
- 돌아 프록시가 초기화되면 객체 (직렬화에 대한 올바른 유형을)
- NULL을 반환는 프록시는 DataContra, 지금까지 너무 좋아
을 초기화되어 있지 않은 경우 ctSurrogate는 직렬화,이 작업의 수행 및 직렬화 복원 할 때 나는 다음과 같은 오류가 클라이언트에 깔끔하게 메시지를 보냅니다
입력 유형 '으로 System.Object'의 개체를 캐스팅 할 수 없습니다'XXXXXXXXXX'
이 시점에서 도대체 왜 NULL valua를 캐스팅합니까? 이것은 내가이 광기가 무엇인지를 NULL로 만들 수 없다는 것을 의미합니까?
그래서 DataContractSurrogate가 프록시 대신 NULL 값을 처리하는 방식에 차이가 있는지 확인하기로했습니다. 기본적으로 DataContractSurrogate가 나를 위해 대신이 NULL 대신 수동으로 앞에서 언급 한 속성을 설정합니다.
Magically, this works ... 정말 내 턱을 떨어 뜨리므로, 나는 무슨 일이 일어나고 있는지를 알기 위해 DataContractSurrogate의 다른 메소드를 밟기로 결정했다.
내가 어떤 이유로 수동으로 NULL 속성을 사용하면 (대부분 맨 위에있는 일부 레이어가 알리지 않기 때문에) GetObjectToSerialize가 호출되지 않습니다. 분명히 NULL로 속성을 수동으로 설정하지 않으면 메서드가 호출되고 프록시/초기화 된 개체 대신 NULL이 반환됩니다. 여기
사람에 흥미 그 넣다 내 DataContractSurrogate에서 두 가지 방법은 다음과 같습니다public Type GetDataContractType(Type type)
{
// Serialize proxies as the base type
if (typeof(INHibernateProxy).IsAssignableFrom(type))
{
type = type.GetType().BaseType;
}
// Serialize persistent collections as the collection interface type
if (typeof(IPersistentCollection).IsAssignableFrom(type))
{
foreach (Type collInterface in type.GetInterfaces())
{
if (collInterface.IsGenericType)
{
type = collInterface;
break;
}
else if (!collInterface.Equals(typeof(IPersistentCollection)))
{
type = collInterface;
}
}
}
return type;
}
public object GetObjectToSerialize(object obj, Type targetType)
{
// Serialize proxies as the base type
if (obj is INHibernateProxy)
{
ILazyInitializer init = ((INHibernateProxy)obj).HibernateLazyInitializer;
if (init.IsUninitialized)
{
obj = null;
}
else
{
obj = init.GetImplementation();
}
}
// Serialize persistent collections as the collection interface type
if (obj is IPersistentCollection)
{
//return
if (!((IPersistentCollection)obj).WasInitialized)
{
Type type = typeof(Collection<>).MakeGenericType(obj.GetType().GetGenericArguments());
obj = Activator.CreateInstance(type);
}
}
return obj;
}
은 무엇 궁금하고있어 내가이 작업을 얻을 수있는 방법이다, 나는 아무 생각없이 내 presisted를 반환 할 수 있도록하려면 개체 (예, DTO가 이것을 해결할 수는 있지만 길을 가고 싶지 않습니다.이 기능을 IMO에서 사용하도록 유지하는 것이 더 많은 작업입니다).
누구나이 작업을 수행하는 방법에 대한 아이디어가 있습니다 (클라이언트 측에서 GetObjectToSerialize가 호출되지 않고 유형이 요청 된 다음 BAM이 폭발 함).
편집 :
이 메시지는 직렬화 이후 :
이<OnReceiveCall xmlns="http://tempuri.org/">
<call xmlns:b="http://schemas.datacontract.org/2004/07/TelephoneExchange.Entities" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<b:Begin>2012-10-03T14:57:20</b:Begin>
**<b:CallingTelephone i:type="c:anyType" xmlns:c="http://www.w3.org/2001/XMLSchema"></b:CallingTelephone>**
<b:End i:nil="true"></b:End>
<b:HasRecording>false</b:HasRecording>
<b:ID>149688</b:ID>
<b:Inputs></b:Inputs>
<b:LeftInQueue>false</b:LeftInQueue>
<b:RecipientTelephone>
<b:IsInternal>true</b:IsInternal>
<b:Name>604</b:Name>
<b:Number>604</b:Number>
</b:RecipientTelephone>
<b:TransUniqueID i:nil="true"></b:TransUniqueID>
</call>
</OnReceiveCall>
사이의 비트 **와 ** 관심의 속성입니다.도대체 내가
:-)이 일을 어떻게 ...<OnReceiveCall xmlns="http://tempuri.org/">
<call xmlns:d4p1="http://schemas.datacontract.org/2004/07/TelephoneExchange.Entities" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<d4p1:Begin>2012-10-03T15:04:18</d4p1:Begin>
**<d4p1:CallingTelephone i:nil="true"></d4p1:CallingTelephone>**
<d4p1:End i:nil="true"></d4p1:End>
<d4p1:HasRecording>false</d4p1:HasRecording>
<d4p1:ID>149721</d4p1:ID>
<d4p1:Inputs></d4p1:Inputs>
<d4p1:LeftInQueue>false</d4p1:LeftInQueue>
<d4p1:RecipientTelephone>
<d4p1:IsInternal>true</d4p1:IsInternal>
<d4p1:Name>604</d4p1:Name>
<d4p1:Number>604</d4p1:Number>
</d4p1:RecipientTelephone>
<d4p1:TransUniqueID i:nil="true"></d4p1:TransUniqueID>
</call>
</OnReceiveCall>
주 차이 .... 이제 질문은 : 내가 수동으로 속성을 null로 할 때
는 XML은 다음과 같습니다
type.GetType(). BaseType에 문제가없는 것 같습니다. GetDataContractType은 항상 올바른 형식을 반환합니다. (Never System.Object). 귀하의 제안을 시도해보십시오. 그리고 그것은 이미 존재하는 코드와 똑같은 결과를 낳았습니다. 메소드에서 반환 된 값이 정확하기 때문에이 부분이 맞는지 아닌지는 문제가 아닌 것으로 보입니다. System.Object가 아니라 올바른 참조 유형) –
문제가 직렬화 내부에있는 것 같지 않습니다 (솔루션이있을 수 있지만 직렬화 중에 예외가 발생하지 않음) 예외는 DEserializing 중에 클라이언트에 발생합니다. –
기본적으로 클라이언트는 캐스팅 예외를 반환하는 'XXXXXXX'형식으로 직렬화하려고하는 System.Object (NULL 값이어야 함)를 수신합니다. 어쩌면 그것은 실제 XML을 라인을 통해 전송하는 것이 좋겠지 만, XML을 서비스로 보내거나 클라이언트가받는 방법을 모르겠습니다. –