I have some web methods that return my objects back as serialized XML. It is only serializing the NHibernate-mapped properties of the object... anyone have some insight? I
Agree with sirrocco, I've had the most awful time trying to serialize NHibernate entities through WCF, and eventually went with a DTO solution done generically through reflection.
Edit: The entire solution is too big to post here, and is customized for my needs ofcourse, so I'll post a few relevant sections:
[DataContract]
public class DataTransferObject
{
private Dictionary propertyValues = new Dictionary();
private Dictionary fieldValues = new Dictionary();
private Dictionary relatedEntitiesValues = new Dictionary();
private Dictionary primaryKey = new Dictionary();
private Dictionary> subEntities = new Dictionary>();
...
public static DataTransferObject ConvertEntityToDTO(object entity,Type transferType)
{
DataTransferObject dto = new DataTransferObject();
string[] typePieces = transferType.AssemblyQualifiedName.Split(',');
dto.AssemblyName = typePieces[1];
dto.TransferType = typePieces[0];
CollectPrimaryKeyOnDTO(dto, entity);
CollectPropertiesOnDTO(dto, entity);
CollectFieldsOnDTO(dto, entity);
CollectSubEntitiesOnDTO(dto, entity);
CollectRelatedEntitiesOnDTO(dto, entity);
return dto;
}
....
private static void CollectPropertiesOnDTO(DataTransferObject dto, object entity)
{
List transferProperties = ReflectionHelper.GetProperties(entity,typeof(PropertyAttribute));
CollectPropertiesBasedOnFields(entity, transferProperties);
foreach (PropertyInfo property in transferProperties)
{
object propertyValue = ReflectionHelper.GetPropertyValue(entity, property.Name);
dto.PropertyValues.Add(property.Name, propertyValue);
}
}
then, when you want to resurrect the DTO:
private static DTOConversionResults ConvertDTOToEntity(DataTransferObject transferObject,object parent)
{
DTOConversionResults conversionResults = new DTOConversionResults();
object baseEntity = null;
ObjectHandle entity = Activator.CreateInstance(transferObject.AssemblyName,
transferObject.TransferType);
if (entity != null)
{
baseEntity = entity.Unwrap();
conversionResults.Add(UpdatePrimaryKeyValue(transferObject, baseEntity));
conversionResults.Add(UpdateFieldValues(transferObject, baseEntity));
conversionResults.Add(UpdatePropertyValues(transferObject, baseEntity));
conversionResults.Add(UpdateSubEntitiesValues(transferObject, baseEntity));
conversionResults.Add(UpdateRelatedEntitiesValues(transferObject, baseEntity,parent));
....
private static DTOConversionResult UpdatePropertyValues(DataTransferObject transferObject, object entity)
{
DTOConversionResult conversionResult = new DTOConversionResult();
foreach (KeyValuePair values in transferObject.PropertyValues)
{
try
{
ReflectionHelper.SetPropertyValue(entity, values.Key, values.Value);
}
catch (Exception ex)
{
string failureReason = "Failed to set property " + values.Key + " value " + values.Value;
conversionResult.Failed = true;
conversionResult.FailureReason = failureReason;
Logger.LogError(failureReason);
Logger.LogError(ExceptionLogger.BuildExceptionLog(ex));
}
}
return conversionResult;
}