I have some trouble when I try to map object to int.
My classes and method where convert:
[Serializable]
public class ProfileProperty
{
public object PropertyValue { get; set; }
public bool IsVisible { get; set; }
public ProfileProperty(object value, bool isVisible = true)
{
this.PropertyValue = value;
this.IsVisible = isVisible;
}
public ProfileProperty()
{
this.IsVisible = true;
}
public T GetValue<T>()
{
return (T)this.PropertyValue;
}
public override string ToString()
{
if (this.PropertyValue != null)
{
return this.PropertyValue.ToString();
}
return string.Empty;
}
}
[Serializable]
public class ProfileProperty
{
public object PropertyValue { get; set; }
public bool IsVisible { get; set; }
public ProfileProperty(object value, bool isVisible = true)
{
this.PropertyValue = value;
this.IsVisible = isVisible;
}
public ProfileProperty()
{
this.IsVisible = true;
}
public T GetValue<T>()
{
return (T)this.PropertyValue;
}
public override string ToString()
{
if (this.PropertyValue != null)
{
return this.PropertyValue.ToString();
}
return string.Empty;
}
}
public static class Helper
{
public static ProfileModel PopulProfMod(Profile profile)
{
var mapper = ObjectMapperManager.DefaultInstance.GetMapper<Profile, ProfileModel>(new DefaultMapConfig()
.IgnoreMembers<Profile, ProfileModel>(new string[] { "GetValue", "ToString" }));
ProfileModel prof = new ProfileModel();
if (profile != null)
{
prof = mapper.Map(profile);
//prof.Age = (int)profile.Age.PropertyValue;
prof.Visibility = new List<string>();
}
//Some code
return prof;
}
}
When mapped property Age is 0 but profile:
Profile profile = new Profile()
{
Age = new ProfileProperty() { IsVisible = true, PropertyValue = 17 },
Comments = 2,
UserName = "Luck",
FirstName = new ProfileProperty() { IsVisible = false, PropertyValue = "Alex" }
};
You need a converter:
new DefaultMapConfig()
.IgnoreMembers<Profile, ProfileModel>(new string[] { "GetValue", "ToString" }))
.ConvertUsing<ProfileProperty, int>(s => (int)s.PropertyValue)
Related
I'm using reflection to order by list of objects.
I would like to order this list on a property of a nested object.
This is the code in which I get the list, and I do the sorting of the list
List<DocumentModel> documentList;
if (contractid == -1)
documentList = helpsi.framework.core.CustomerProvider.DocumentModel.getAllDocumentModelListByCustomer(custid, custtypeid);
else
documentList = helpsi.framework.core.CustomerProvider.DocumentModel.getAllDocumentModelListGridByContract(contractid);
if (sord.Equals("asc")) documentList = documentList.OrderBy(x => x.GetType().GetProperty(sidx.ToUpper()).GetValue(x, null)).ToList();
else documentList = documentList.OrderByDescending(x => x.GetType().GetProperty(sidx.ToUpper()).GetValue(x, null)).ToList();
The DocumentModel object has a DocumentModelType property that contains a DocumentStateDesc string property.
Can I sort the list by the DocumentTypeDesc property using reflection? What can I use in the sidx parameter?
Thanks
This is the DocumentModel class
public class DocumentModel : ObjBase
{
#region Attributi
private long _id;
private string _documentModel;
private long? _documentModelTypeId;
private long? _documentModelIssuingEntityId;
private string _documentModelFilename;
private string _documentModelPath;
private DateTime? _documentModelStart;
private DateTime? _documentModelEnd;
private string _documentModelVersion;
private long _contractId;
private string _contractNumber;
private long _contractTypeId;
private long _contractStateId;
private string _contractState;
private long _documentModelStateId;
private string _documentModelValoId;
private DateTime? _documentModelUploadDate;
private byte[] _documentModelContent;
private long _documentModelFilter;
private bool _flagDeleted;
private long _userId;
private int _orderDocumentModel = 0;
private string _placeOfIssue;
private string _issuingEntity;
private DateTime? _releaseDate;
private int? _idOpInsert;
private int? _idOpId;
private long? _customerId;
private long? _customerTypeId;
private string _customerNumber;
private DateTime? _documentModelInvalidated;
private bool _flagValidating;
private string _fileRemotePath;
private long? _folderId;
private string _folderName;
protected new HELPSI_Database HELPSI_Database = Common.HELPSI_Database.HELPSI_Anag;
[XmlElement(ElementName = "CODE_DOCUMENT_MODEL_ID")]
public long CODE_DOCUMENT_MODEL_ID
{
get { return _id; }
set { _id = value; }
}
[XmlElement(ElementName = "DESC_DOCUMENT_MODEL")]
public string DESC_DOCUMENT_MODEL
{
get { return _documentModel; }
set { _documentModel = value; }
}
[XmlElement(ElementName = "CODE_DOCUMENT_MODEL_TYPE_ID")]
public long? CODE_DOCUMENT_MODEL_TYPE_ID
{
get { return _documentModelTypeId; }
set { _documentModelTypeId = value; }
}
[XmlElement(ElementName = "CODE_DOCUMENT_MODEL_ISSUING_ENTITY_ID")]
public long? CODE_DOCUMENT_MODEL_ISSUING_ENTITY_ID
{
get { return _documentModelIssuingEntityId; }
set { _documentModelIssuingEntityId = value; }
}
[XmlElement(ElementName = "DESC_DOCUMENT_MODEL_FILENAME", IsNullable = true)]
public string DESC_DOCUMENT_MODEL_FILENAME
{
get { return _documentModelFilename; }
set { _documentModelFilename = value; }
}
[XmlElement(ElementName = "DESC_DOCUMENT_MODEL_PATH", IsNullable=true)]
public string DESC_DOCUMENT_MODEL_PATH
{
get { return _documentModelPath; }
set { _documentModelPath = value; }
}
[XmlElement(ElementName = "DATE_DOCUMENT_MODEL_START")]
public DateTime? DATE_DOCUMENT_MODEL_START
{
get { return _documentModelStart; }
set { _documentModelStart = value; }
}
[XmlElement(ElementName = "DATE_DOCUMENT_MODEL_END")]
public DateTime? DATE_DOCUMENT_MODEL_END
{
get { return _documentModelEnd; }
set { _documentModelEnd = value; }
}
[XmlElement(ElementName = "DESC_DOCUMENT_MODEL_VERSION", IsNullable = true)]
public string DESC_DOCUMENT_MODEL_VERSION
{
get { return _documentModelVersion; }
set { _documentModelVersion = value; }
}
[XmlElement(ElementName = "CODE_CONTRACT_ID")]
public long CODE_CONTRACT_ID
{
get { return _contractId; }
set { _contractId = value; }
}
[XmlElement(ElementName = "FLAG_DELETED")]
public bool FLAG_DELETED
{
get { return _flagDeleted; }
set { _flagDeleted = value; }
}
[XmlElement(ElementName = "CODE_USER_ID")]
public long CODE_USER_ID
{
get { return _userId; }
set { _userId = value; }
}
[XmlElement(ElementName = "ORDER_DOCUMENT_MODEL")]
public int ORDER_DOCUMENT_MODEL
{
get { return _orderDocumentModel; }
set { _orderDocumentModel = value;}
}
private DocumentModelType _documentModelType;
[XmlElement(ElementName = "DocumentModelType", IsNullable = true)]
public DocumentModelType documentModelType
{
get { return _documentModelType; }
set { _documentModelType = value; }
}
private DocumentModelState _documentModelState;
[XmlElement(ElementName = "DocumentModelState", IsNullable = true)]
public DocumentModelState documentModelState
{
get { return _documentModelState; }
set { _documentModelState = value; }
}
private DocumentModelIssuingEntity _documentModelIssuingEntity;
[XmlElement(ElementName = "DocumentModelIssuingEntity", IsNullable = true)]
public DocumentModelIssuingEntity documentModelIssuingEntity
{
get { return _documentModelIssuingEntity; }
set { _documentModelIssuingEntity = value; }
}
//private DocumentModelFolder _documentModelFolder;
//[XmlElement(ElementName = "DocumentModelFolder", IsNullable = true)]
//public DocumentModelFolder documentModelFolder
//{
// get { return _documentModelFolder; }
// set { _documentModelFolder = value; }
//}
[XmlElement(ElementName = "CODE_DOCUMENT_MODEL_STATE_ID")]
public long CODE_DOCUMENT_MODEL_STATE_ID
{
get { return _documentModelStateId; }
set { _documentModelStateId = value; }
}
[XmlElement(ElementName = "VALO_DOCUMENT_MODEL_ID")]
public string VALO_DOCUMENT_MODEL_ID
{
get { return _documentModelValoId; }
set { _documentModelValoId = value; }
}
[XmlElement(ElementName = "DATE_DOCUMENT_MODEL_UPLOAD")]
public DateTime? DATE_DOCUMENT_MODEL_UPLOAD
{
get { return _documentModelUploadDate; }
set { _documentModelUploadDate = value; }
}
[XmlElement(ElementName = "DESC_DOCUMENT_MODEL_CONTENT")]
public byte[] DESC_DOCUMENT_MODEL_CONTENT
{
get { return _documentModelContent; }
set { _documentModelContent = value; }
}
[XmlElement(ElementName = "CODE_DOCUMENT_MODEL_FILTER_ID")]
public long CODE_DOCUMENT_MODEL_FILTER_ID
{
get { return _documentModelFilter; }
set { _documentModelFilter = value; }
}
private long _code_siteId;
[XmlElement(ElementName = "CODE_SITEID")]
public long CODE_SITEID
{
get { return _code_siteId; }
set { _code_siteId = value; }
}
[XmlElement(ElementName = "DESC_DOCUMENT_RELEASE_PLACE")]
public string DESC_DOCUMENT_RELEASE_PLACE
{
get { return _placeOfIssue; }
set { _placeOfIssue = value; }
}
[XmlElement(ElementName = "DESC_DOCUMENT_RELEASED_BY")]
public string DESC_DOCUMENT_RELEASED_BY
{
get { return _issuingEntity; }
set { _issuingEntity = value; }
}
[XmlElement(ElementName = "DATE_DOCUMENT_RELEASED")]
public DateTime? DATE_DOCUMENT_RELEASED
{
get { return _releaseDate; }
set { _releaseDate = value; }
}
[XmlElement(ElementName = "CODE_OP_INSERT_ID")]
public int? CODE_OP_INSERT_ID
{
get { return _idOpInsert; }
set { _idOpInsert = value; }
}
[XmlElement(ElementName = "CODE_OP_ID_ID")]
public int? CODE_OP_ID_ID
{
get { return _idOpId; }
set { _idOpId = value; }
}
[XmlElement(ElementName = "CODE_CUSTOMERID")]
public long? CODE_CUSTOMERID
{
get { return _customerId; }
set { _customerId = value; }
}
[XmlElement(ElementName = "CODE_CUSTOMERTYPEID")]
public long? CODE_CUSTOMERTYPEID
{
get { return _customerTypeId; }
set { _customerTypeId = value; }
}
[XmlElement(ElementName = "DATE_DOCUMENT_MODEL_INVALIDATED")]
public DateTime? DATE_DOCUMENT_MODEL_INVALIDATED
{
get { return _documentModelInvalidated; }
set { _documentModelInvalidated = value; }
}
[XmlElement(ElementName = "FLAG_VALIDATING")]
public bool FLAG_VALIDATING
{
get { return _flagValidating; }
set { _flagValidating = value; }
}
[XmlElement(ElementName = "CODE_CONTRACT_STATES_ID")]
public long CODE_CONTRACT_STATES_ID
{
get { return _contractStateId; }
set { _contractStateId = value; }
}
[XmlElement(ElementName = "DESC_CONTRACT_STATES")]
public string DESC_CONTRACT_STATES
{
get { return _contractState; }
set { _contractState = value; }
}
[XmlElement(ElementName = "CODE_CONTRACT_TYPE_ID")]
public long CODE_CONTRACT_TYPE_ID
{
get { return _contractTypeId; }
set { _contractTypeId = value; }
}
[XmlElement(ElementName = "DESC_CONTRACT_NUMBER")]
public string DESC_CONTRACT_NUMBER
{
get { return _contractNumber; }
set { _contractNumber = value; }
}
[XmlElement(ElementName = "DESC_CONTACT_NUMBER")]
public string DESC_CONTACT_NUMBER
{
get { return _customerNumber; }
set { _customerNumber = value; }
}
[XmlElement(ElementName = "CODE_DOCUMENT_MODEL_FOLDER_ID")]
public long? CODE_DOCUMENT_MODEL_FOLDER_ID
{
get { return _folderId; }
set { _folderId = value; }
}
[XmlElement(ElementName = "DocumentModelFolderName")]
public string DocumentModelFolderName
{
get { return _folderName; }
set { _folderName = value; }
}
[XmlElement(ElementName = "DESC_FILEREMOTEPATH")]
public string DESC_FILEREMOTEPATH
{
get { return _fileRemotePath; }
set { _fileRemotePath = value; }
}
#endregion
}
And this is the DocumentModelType Class
public class DocumentModelType : ObjBase
{
#region Attributi
private long _id;
private string _documentModelType;
private bool _flagDeleted;
private long _userId;
protected new HELPSI_Database HELPSI_Database = Common.HELPSI_Database.HELPSI_Anag;
[XmlElement(ElementName = "CODE_DOCUMENT_MODEL_TYPE_ID")]
public long CODE_DOCUMENT_MODEL_TYPE_ID
{
get { return _id; }
set { _id = value; }
}
[XmlElement(ElementName = "DESC_DOCUMENT_MODEL_TYPE")]
public string DESC_DOCUMENT_MODEL_TYPE
{
get { return _documentModelType; }
set { _documentModelType = value; }
}
[XmlElement(ElementName = "FLAG_DELETED")]
public bool FLAG_DELETED
{
get { return _flagDeleted; }
set { _flagDeleted = value; }
}
[XmlElement(ElementName = "CODE_USER_ID")]
public long CODE_USER_ID
{
get { return _userId; }
set { _userId = value; }
}
#endregion
}
You should be using x => x.DocumentModelType.GetType().GetProperty(sidx.ToUpper()).GetValue(x.DocumentModelType, null) inside OrderBy clause. Here sidx should be DocumentStateDesc as you mentioned that you want order on this column.
Complete code will be like below.
List<DocumentModel> documentList;
if (contractid == -1)
documentList = helpsi.framework.core.CustomerProvider.DocumentModel.getAllDocumentModelListByCustomer(custid, custtypeid);
else
documentList = helpsi.framework.core.CustomerProvider.DocumentModel.getAllDocumentModelListGridByContract(contractid);
if (sord.Equals("asc"))
documentList = documentList.OrderBy(x => x.DocumentModelType.GetType().GetProperty(sidx.ToUpper()).GetValue(x.DocumentModelType, null)).ToList();
else
documentList = documentList.OrderByDescending(x => x.DocumentModelType.GetType().GetProperty(sidx.ToUpper()).GetValue(x.DocumentModelType, null)).ToList();
One quick and dirty fix is to introduce property in parent class that just returns the property value of another property. Just don't assign XmlElement attribute to it. If the classes are auto-generated you can't change them, but they are probably declared as partial, and then you can add this new property in additional class definition.
public string DocumentModelType_DocumentStateDesc { get => DocumentModelType.DocumentStateDesc; }
But if you want to have a general solution for several properties with several sub-properties then some sort of pathing is required. You could String.Split sidx on some delimiter like '\' or '.', use recursion, and then OrderBy the last item in the path.
All the objects in our system inherit a base class which has got a property of type object.
I have tried adding protoignore attribute to all the properties of the base class as well but that doesn't seem to work as well.
class Program
{
static void Main(string[] args)
{
Vehicle vehicle = new Vehicle();
vehicle.BodyStyleDescription = "4x4";
vehicle.BodyStyleText = "Prestige Medium";
dynamic protobufModel = TypeModel.Create();
AddTypeToModel<Vehicle>(protobufModel);
using (MemoryStream compressed = new MemoryStream())
{
using (GZipStream gzip = new GZipStream(compressed, CompressionMode.Compress, true))
{
protobufModel.Serialize(gzip, vehicle);
}
string str = Convert.ToBase64String(compressed.GetBuffer(), 0, Convert.ToInt32(compressed.Length));
}
}
public static MetaType AddTypeToModel<T>(RuntimeTypeModel typeModel)
{
var properties = typeof(T).GetProperties().Select(p => p.Name).OrderBy(name => name);
return typeModel.Add(typeof(T), true).Add(properties.ToArray());
}
}
Following is the hierarchy of the object
public interface IObjectBaseClass
{
[ProtoIgnore()]
object Parent { get; set; }
[ProtoIgnore()]
bool IsSaved { get; set; }
[ProtoIgnore()]
string XmlAtLoad { get; set; }
}
public class ObjectBaseClass : IObjectBaseClass
{
public ObjectBaseClass()
{
}
[ProtoIgnore()]
internal object _Parent;
[ProtoIgnore()]
internal bool _IsSaved;
[ProtoIgnore()]
internal string _XmlAtLoad;
[ProtoIgnore()]
public bool IsSaved
{
get { return _IsSaved; }
set { _IsSaved = value; }
}
[ProtoIgnore()]
public object Parent
{
get { return _Parent; }
set { _Parent = value; }
}
[ProtoIgnore()]
public string XmlAtLoad
{
get { return _XmlAtLoad; }
set { _XmlAtLoad = value; }
}
}
public class Vehicle : ObjectBaseClass
{
private string _BodyStyleText;
private string _BodyStyleDescription;
public string BodyStyleDescription
{
get { return _BodyStyleDescription; }
set { _BodyStyleDescription = value; }
}
public string BodyStyleText
{
get { return _BodyStyleText; }
set { _BodyStyleText = value; }
}
}
Your problem is that when you do typeModel.Add(typeof(T), true).Add(properties.ToArray()) you are adding all properties of T to the runtime type model, including those marked with ProtoIgnore. You can see this by calling the debugging method protobufModel.GetSchema(typeof(Vehicle)) which returns:
message Object {
}
message Vehicle {
optional string BodyStyleDescription = 1;
optional string BodyStyleText = 2;
optional bool IsSaved = 3;
optional Object Parent = 4;
optional string XmlAtLoad = 5;
}
To avoid adding properties marked with [ProtoIgnore], you could do:
public static MetaType AddTypeToModel<T>(RuntimeTypeModel typeModel)
{
var properties = typeof(T)
.GetProperties()
.Where(p => !p.GetCustomAttributes<ProtoIgnoreAttribute>().Any())
.Select(p => p.Name)
.OrderBy(name => name);
return typeModel.Add(typeof(T), true).Add(properties.ToArray());
}
Alternatively, since you are manually annotating some of your models with protobuf attributes anyway, you could mark the derived types with [ProtoContract(ImplicitFields = ImplicitFields.AllPublic)], e.g.:
[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
public class Vehicle : ObjectBaseClass
{
private string _BodyStyleText;
private string _BodyStyleDescription;
public string BodyStyleDescription
{
get { return _BodyStyleDescription; }
set { _BodyStyleDescription = value; }
}
public string BodyStyleText
{
get { return _BodyStyleText; }
set { _BodyStyleText = value; }
}
}
Using either method, the schema for Vehicle becomes:
message Vehicle {
optional string BodyStyleDescription = 1;
optional string BodyStyleText = 2;
}
This is what you require.
public class OrderXml
{
public enum DeliveryType { FTP, Email, HDD, Tape, Aspera, MLT };
public class Order
{
public int UserId { get; private set; }
public int OrderBinId { get; private set; }
public int TenantId { get; private set; }
public Delivery Delivery { get; set; }
public Recipient Recipient { get; private set; }
public string[] AssetDmGuids { get; set; }
public Order(int orderBinId, string[] assetDmGuids, DeliveryType type, int recipientId, string recipientName)
{
Delivery = new Delivery(type);
Recipient = new Recipient(recipientId, recipientName);
// UserId = SessionHelper.Instance.GetUserId();
// TenantId = SessionHelper.Instance.GetTenantID().ToString();
OrderBinId = orderBinId;
AssetDmGuids = assetDmGuids;
}
public void GetXml()
{
}
}
public class Recipient
{
int _id;
string _name = string.Empty;
public Recipient(int id, string name)
{
this._id = id;
this._name = name;
}
public int Id { get { return _id; } }
public string Name { get { return _name; } }
}
public class Delivery
{
DeliveryType _deliveryType;
string _ftpLocation = string.Empty;
string _ftpPath = string.Empty;
string[] _emailAddresses;
string _deliveryAddress = string.Empty;
string _deliveryComments = string.Empty;
string _asperaLocation = string.Empty;
public string FtpPath
{
get { return _ftpPath; }
set { _ftpPath = value; }
}
public string[] EmailAddresses
{
get { return _emailAddresses; }
set { _emailAddresses = value; }
}
public string DeliveryAddress
{
get { return _deliveryAddress; }
set { _deliveryAddress = value; }
}
public string DeliveryComments
{
get { return _deliveryComments; }
set { _deliveryComments = value; }
}
public string AsperaLocation
{
get { return _asperaLocation; }
set { _asperaLocation = value; }
}
public string FtpLocation
{
get { return _ftpLocation; }
set { _ftpLocation = value; }
}
public Delivery(DeliveryType type)
{
_deliveryType = type;
}
}
public static void Main()
{
Order ord = new Order(1, new string[] { "123", "124", "125" }, DeliveryType.Tape, 1, "vh1");
}
}
public XmlDocument GetXml()
{
XmlDocument retValue = new XmlDocument();
try
{
XmlSerializer xs = new XmlSerializer(this.GetType());
Stream stream = new MemoryStream();
xs.Serialize( stream, toSerialize );
stream.Position = 0;
retValue.Load( stream );
}
catch (Exception ex)
{
}
return retValue;
}
This is a variation of Marc Gravels's answer
I'd extent Marc Gravels's helpful example to view nested objects in a generic way. But System throws an System.Reflection.TargetException.
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
public class Author
{
public string LastName { get; set; }
public string FirstName { get; set; }
}
public class BookDetails
{
public string Title { get; set; }
public int TotalRating { get; set; }
public int Occurrence { get; set; }
public Author Author { get; set; }
}
//public class MyBindingSource<T> : BindingSource
class MyList<T> : List<T>, ITypedList
{
public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
{
var origProps = TypeDescriptor.GetProperties(typeof(T));
List<PropertyDescriptor> newProps = new List<PropertyDescriptor>(origProps.Count);
foreach (PropertyDescriptor prop in origProps)
{
var childProps = TypeDescriptor.GetProperties(prop.GetType());
if ((childProps.Count == 0) || isSimpleType(prop))
{
newProps.Add(prop);
}
else
{
foreach (PropertyDescriptor childProp in childProps)
{
newProps.Add(new MyPropertyDescriptor(prop, childProp));
}
}
}
return new PropertyDescriptorCollection(newProps.ToArray());
}
private static bool isSimpleType(PropertyDescriptor prop)
{
if (prop.PropertyType.BaseType == typeof(ValueType)) return true;
if (prop.PropertyType == typeof(string)) return true;
if (prop.PropertyType.BaseType != typeof(Object)) return true;
return false;
}
public string GetListName(PropertyDescriptor[] listAccessors)
{
return "";
}
}
class MyPropertyDescriptor : PropertyDescriptor
{
private static readonly Attribute[] nix = new Attribute[0];
private readonly PropertyDescriptor parent;
private readonly PropertyDescriptor child;
public MyPropertyDescriptor(PropertyDescriptor parent, PropertyDescriptor child)
: base(parent.Name + "." + child.Name, nix)
{
this.parent = parent;
this.child = child;
}
public override object GetValue(object component)
{
return child.GetValue(component);
}
public override Type PropertyType
{
get { return child.PropertyType; }
}
public override bool IsReadOnly
{
get { return true; }
}
public override void SetValue(object component, object value)
{
throw new NotSupportedException();
}
public override void ResetValue(object component)
{
throw new NotSupportedException();
}
public override bool CanResetValue(object component)
{
return false;
}
public override Type ComponentType
{
get { return parent.ComponentType; }
}
public override bool ShouldSerializeValue(object component)
{
return false;
}
}
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
var author1 = new Author() { FirstName = "Victor", LastName = "Hugo" };
var author2 = new Author() { FirstName = "Moore", LastName = "Thomas" };
var data = new MyList<BookDetails> {
new BookDetails { Title = "abc", TotalRating = 3, Occurrence = 2, Author = author1 },
new BookDetails { Title = "def", TotalRating = 3, Occurrence = 2, Author = author2 },
new BookDetails { Title = "ghi", TotalRating = 3, Occurrence = 2, Author = author1 },
new BookDetails { Title = "jkl", TotalRating = 3, Occurrence = 2, Author = author2 },
};
Application.Run(new Form
{
Controls = {
new DataGridView {
Dock = DockStyle.Fill,
DataSource = data
}
}
});
}
}
You should Change prop.GetType() to prop.PropertyType.
I found the solution by myself:
The error was in the MyPropertyDescriptor!
Correction:
class MyPropertyDescriptor : PropertyDescriptor
{
private static readonly Attribute[] nix = new Attribute[0];
private readonly PropertyDescriptor parent;
private readonly PropertyDescriptor child;
public MyPropertyDescriptor(PropertyDescriptor parent, PropertyDescriptor child)
: base(parent.Name + "." + child.Name, nix)
{
this.parent = parent;
this.child = child;
}
public override object GetValue(object component)
{
var temp = parent.GetValue(component);
if (temp == null) return null;
var temp2 = child.GetValue(temp);
return temp2;
}
public override Type PropertyType
{
get { return child.PropertyType; }
}
public override bool IsReadOnly
{
get { return true; }
}
public override void SetValue(object component, object value)
{
throw new NotSupportedException();
}
public override void ResetValue(object component)
{
throw new NotSupportedException();
}
public override bool CanResetValue(object component)
{
return false;
}
public override Type ComponentType
{
get { return parent.ComponentType; }
}
public override bool ShouldSerializeValue(object component)
{
return false;
}
}
Im haveing some xml that have this structure
<Person Id="*****" Name="*****">
<AccessControlEntries>
<AccessControlEntry Id="*****" Name="****"/>
</AccessControlEntries>
<AccessControls />
<IdentityGroups>
<IdentityGroup Id="****" Name="*****" />
</IdentityGroups></Person>
and i also have this entities
[DataContract(IsReference = true)]
public abstract class EntityBase
{
protected bool serializing;
[DataMember(Order = 1)]
[XmlAttribute()]
public string Id { get; set; }
[DataMember(Order = 2)]
[XmlAttribute()]
public string Name { get; set; }
[OnDeserializing()]
public void OnDeserializing(StreamingContext context)
{
this.Initialize();
}
[OnSerializing()]
public void OnSerializing(StreamingContext context)
{
this.serializing = true;
}
[OnSerialized()]
public void OnSerialized(StreamingContext context)
{
this.serializing = false;
}
public abstract void Initialize();
public string ToXml()
{
var settings = new System.Xml.XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
var sb = new System.Text.StringBuilder();
using (var writer = System.Xml.XmlWriter.Create(sb, settings))
{
var serializer = new XmlSerializer(this.GetType());
serializer.Serialize(writer, this);
}
return sb.ToString();
}
}
[DataContract()]
public abstract class Identity : EntityBase
{
private EntitySet<AccessControlEntry> accessControlEntries;
private EntitySet<IdentityGroup> identityGroups;
public Identity()
{
Initialize();
}
[DataMember(Order = 3, EmitDefaultValue = false)]
[Association(Name = "AccessControlEntries")]
public EntitySet<AccessControlEntry> AccessControlEntries
{
get
{
if ((this.serializing && (this.accessControlEntries==null || this.accessControlEntries.HasLoadedOrAssignedValues == false)))
{
return null;
}
return accessControlEntries;
}
set
{
accessControlEntries.Assign(value);
}
}
[DataMember(Order = 4, EmitDefaultValue = false)]
[Association(Name = "IdentityGroups")]
public EntitySet<IdentityGroup> IdentityGroups
{
get
{
if ((this.serializing && (this.identityGroups == null || this.identityGroups.HasLoadedOrAssignedValues == false)))
{
return null;
}
return identityGroups;
}
set
{
identityGroups.Assign(value);
}
}
private void attach_accessControlEntry(AccessControlEntry entity)
{
entity.Identities.Add(this);
}
private void dettach_accessControlEntry(AccessControlEntry entity)
{
entity.Identities.Remove(this);
}
private void attach_IdentityGroup(IdentityGroup entity)
{
entity.MemberIdentites.Add(this);
}
private void dettach_IdentityGroup(IdentityGroup entity)
{
entity.MemberIdentites.Add(this);
}
public override void Initialize()
{
this.accessControlEntries = new EntitySet<AccessControlEntry>(
new Action<AccessControlEntry>(this.attach_accessControlEntry),
new Action<AccessControlEntry>(this.dettach_accessControlEntry));
this.identityGroups = new EntitySet<IdentityGroup>(
new Action<IdentityGroup>(this.attach_IdentityGroup),
new Action<IdentityGroup>(this.dettach_IdentityGroup));
}
}
[XmlType(TypeName = "AccessControlEntry")]
public class AccessControlEntry : EntityBase, INotifyPropertyChanged
{
private EntitySet<Service> services;
private EntitySet<Identity> identities;
private EntitySet<Permission> permissions;
public AccessControlEntry()
{
services = new EntitySet<Service>(new Action<Service>(attach_Service), new Action<Service>(dettach_Service));
identities = new EntitySet<Identity>(new Action<Identity>(attach_Identity), new Action<Identity>(dettach_Identity));
permissions = new EntitySet<Permission>(new Action<Permission>(attach_Permission), new Action<Permission>(dettach_Permission));
}
[DataMember(Order = 3, EmitDefaultValue = false)]
public EntitySet<Permission> Permissions
{
get {
if ((this.serializing && (this.permissions.HasLoadedOrAssignedValues == false)))
{
return null;
}
return permissions;
}
set
{
permissions.Assign(value);
}
}
[DataMember(Order = 4, EmitDefaultValue = false)]
public EntitySet<Identity> Identities
{
get
{
if ((this.serializing && (this.identities.HasLoadedOrAssignedValues == false)))
{
return null;
}
return identities;
}
set
{
identities.Assign(identities);
}
}
[DataMember(Order = 5, EmitDefaultValue = false)]
public EntitySet<Service> Services
{
get
{
if ((this.serializing && (this.services.HasLoadedOrAssignedValues == false)))
{
return null;
}
return services;
}
set
{
services.Assign(value);
}
}
private void attach_Permission(Permission entity)
{
entity.AccessControlEntires.Add(this);
}
private void dettach_Permission(Permission entity)
{
entity.AccessControlEntires.Remove(this);
}
private void attach_Identity(Identity entity)
{
entity.AccessControlEntries.Add(this);
}
private void dettach_Identity(Identity entity)
{
entity.AccessControlEntries.Remove(this);
}
private void attach_Service(Service entity)
{
entity.AccessControlEntries.Add(this);
}
private void dettach_Service(Service entity)
{
entity.AccessControlEntries.Remove(this);
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(name));
}
#endregion
public override void Initialize()
{
throw new NotImplementedException();
}
}
[DataContract()]
[XmlType(TypeName = "Person")]
public class Person : Identity
{
private EntityRef<Login> login;
[DataMember(Order = 3)]
[XmlAttribute()]
public string Nombre { get; set; }
[DataMember(Order = 4)]
[XmlAttribute()]
public string Apellidos { get; set; }
[DataMember(Order = 5)]
public Login Login {
get
{
return login.Entity;
}
set
{
var previousValue = this.login.Entity;
if (((previousValue != value) || (this.login.HasLoadedOrAssignedValue == false)))
{
if ((previousValue != null))
{
this.login.Entity = null;
previousValue.Person = null;
}
this.login.Entity = value;
if ((value != null))
value.Person = this;
}
}
}
public override void Initialize()
{
base.Initialize();
}
}
[DataContract()]
[XmlType(TypeName = "Login")]
public class Login : EntityBase
{
private EntityRef<Person> person;
[DataMember(Order = 3)]
public string UserID { get; set; }
[DataMember(Order = 4)]
public string Contrasena { get; set; }
[DataMember(Order = 5)]
public Domain Dominio
{
get;
set;
}
public Person Person
{
get
{
return person.Entity;
}
set
{
var previousValue = this.person.Entity;
if (((previousValue != value) || (this.person.HasLoadedOrAssignedValue == false)))
{
if ((previousValue != null))
{
this.person.Entity = null;
previousValue.Login = null;
}
this.person.Entity = value;
if ((value != null))
value.Login = this;
}
}
}
public override void Initialize()
{
throw new NotImplementedException();
}
}
[DataContract()]
[XmlType(TypeName = "IdentityGroup")]
public class IdentityGroup : Identity
{
private EntitySet<Identity> memberIdentities;
public IdentityGroup()
{
Initialize();
}
public override void Initialize()
{
this.memberIdentities = new EntitySet<Identity>(new Action<Identity>(this.attach_Identity), new Action<Identity>(this.dettach_Identity));
}
[DataMember(Order = 3, EmitDefaultValue = false)]
[Association(Name = "MemberIdentities")]
public EntitySet<Identity> MemberIdentites
{
get
{
if ((this.serializing && (this.memberIdentities.HasLoadedOrAssignedValues == false)))
{
return null;
}
return memberIdentities;
}
set
{
memberIdentities.Assign(value);
}
}
private void attach_Identity(Identity entity)
{
entity.IdentityGroups.Add(this);
}
private void dettach_Identity(Identity entity)
{
entity.IdentityGroups.Remove(this);
}
}
[DataContract()]
[XmlType(TypeName = "Group")]
public class Group : Identity
{
public override void Initialize()
{
throw new NotImplementedException();
}
}
but the ToXml() response something like this
<Person xmlns:xsi="************" xmlns:xsd="******" ID="******" Name="*****"/><AccessControlEntries/></Person>
but what i want is something like this
<Person Id="****" Name="***" Nombre="****">
<AccessControlEntries/>
<IdentityGroups/>
</Person>
Try using the following Serialize method:
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
serializer.Serialize(writer, this, ns);