Object to Object Mapping - c#

I have a RESTful service which returns JSON that I am deserialising into classes in c#.
I need to map some of the properties from the deserialised object model into properties in a different class.
However, I would like to do this through an (xml?) config file which can specify the from/to property names, so that mappings can be changed without recompiling code.
For example:
objectA.Name.FirstName = objectB.FirstName
objectA.Name.LastName = objectB.LastName
What is the best way to do this?

You could let something like AutoMapper do the mapping for you.
There are samples in the source code and configuration options in the wiki.

If you want it to to be based on late binding you can use reflection to dynamically execute the property assignments based on xml definitions.
You can see some examples in this asnwer: Set object property using reflection

Related

Read properties from anonymous object

I am generating a OkObjectResult that has anonymous properties:
When i receive data i can see the properties in the debugger / quickwatch:
I am unable to get the property names out of my anonymous object.
Is there a "simple" way?
The solution i found was to search for my desired properties via reflection. Is this the way to to it?
Edit: Even whey using dynamic i am not able to get the properties.
Instead of var use dynamic type for okResult. Thereafter, you can access your properties like: okResult.data and so on...
Update: As Daisy pointed out below, you will need InternalsVisibleTo because the generated anonymous type is internal, and the dynamic binder checks that.

Automatically map asmx-provided xml data to POCO object

In my .net code I am consuming a third-party asmx service that provides me data in Xml format. So basically, I am recieving a structure in a form of XmlNode:
<PostcodeEntry>
<Postcode>13542</Postcode>
<Postcodename>Odessa</Postcodename>
</PostcodeEntry>
Currently, to map it to my POCO object I have to manually iterate through a corresponding ChildNode's and retrieve their InnerText value to get the actual data:
var PostCodeNode = entryNode.SelectSingleNode("Postcode");
if (PostCodeNode != null)
{
result.PostCode = PostCodeNode.InnerText;
}
In case I need to map a large info structure, the code grows to a messy code-scroll.
Is there a way I can improve this so I don't have to write the parsing manually? What is the best practice for this?
I believe that you have different options depending on how you get your data and how you like to design your code etc. From your brief description I can think of at least these two:
Create an XML Serializer - for example by marking up your class with Xml Attributes and de-serialize the XML directly as your desired object via the serializer. The disadvantage of this approach is that you will create a strong coupling between your serializer and your business object. Please take a look at something like this: http://www.switchonthecode.com/tutorials/csharp-tutorial-xml-serialization.
Create a proxy object and map your proxy object to your business object. You can create the proxy object either by using a WSDL exposed by the asmx service, or by using the XSD.exe tool or similar (you may need to first generate an XSD based on the XML if the XML is not already described by an XSD). Then you can map the properties of your proxy object to the properties of your business object. This will provide you a more clean separation between the objects, but at the same time it requires more work.
Br. Morten
You can create SoapClient object for WebService, then you can return the Response as List<>. You need to change the Ouput response to List<>.
example Consilder this the webservice to consume, http://xxx.xx.xxx.xxx/CosmosService/Cm_Service.asmx
then add Service Reference in your application, Click On Advanced Button, change the Collection Type System.Collections.GenericList.
then you can Consume WebService Methods as List<> directly like this
CosmosRef.CM_ServiceSoapClient client = new CosmosRef.CM_ServiceSoapClient();
List<CosmosRef.Product> listProduct = client.GetAllProducts("Computers", 1);
dataGrid1.DataContext = listProduct;

How to set default values to the properties of dynamically loaded types at runtime for XML serialization

I need to serialize dynamically loaded types' classes using XMLSerializer.
When using XML serializer non initialized values are not being serialized. I dont have control over the assemblies I am working with so can not use XML attributes for specifying default values on properties. So I think I need to set all properties and sub properties to their default values recursively and then serialize. ( Please let me know if there is any better way )
Followed this :
Activator.CreateInstance(propType);
but above line complains about not having a parameterless constructor for some types.
Tried this :
subObject = FormatterServices.GetUninitializedObject(propType);
but this one gives an error "value was invalid" with no inner exception.
Please let me know if you need any further information.
If the types in question don't have public parameterless constructors, you'll struggle. You can get around the attributes issue by using the constructor overload that accepts a XmlAttributeOverrides object, which you can use to fully configure the serializer including the default value (via XmlAttributes.XmlDefaultValue), but some things you can't do - and get around the constructor limitation is one of them.
What is the scenario here?
if you want xml, then I would introduce a DTO layer: some objects that look like the ones you're talking about, but are simple and under your control. Ideal for XmlSerializer. You then write code to map between the two
if you just want serialization (and xml is an implementation detail) then there are other serializers that may help. DataContractSerializer or protobuf-net, for example; either would be more versatile here.

C# Custom Attribute Alternatives

Currently, I've created a class with ~30 properties to be set. This is done to build up a URL request later on(ie, "http://www.domain.com/test.htm?var1=a&var2=b...&var30=dd").
The issue I'm facing is the property names don't necessarily match the query variable names(this is intended to be different). For example, I may have a variable titled "BillAddress", whereas the query variable will need to be "as_billaddress".
I have no control over the query variable naming scheme as these are set at an external source.
One possible solution I've used is creating a custom attribute and decorating the properties with their respective query counterparts:
[CustomQueryAttribute("as_billaddress")]
string BillAddress{get;set;}
To retrieve the attribute though, requires a little reflection and due to the larger number of properties, I was curious if there is a neater way to accomplish this functionality. Not so much as setting/retrieving custom attributes without reflection, but being able to tie an alternate string variable to any property.
I've also pondered about setting each variable up as a sort of KeyValuePair, with each key representing the query counterpart, but I didn't get too far in that thought.
To summarize/clarify my above backstory, what would you do to associate a string with a property(not the value of the property)?
As always, any comments are greatly appreciated.
I would probably stick with a custom attribute, but the other potential option would be to do something like hold a static Dictionary that had string and property info (or property name), so you could get/set the property directly via this.
Something like:
static Dictionary<string, PropertyInfo> propertyMap = new Dictionary<string, PropertyInfo>();
static MyClass()
{
Type myClass = typeof(MyClass);
// For each property you want to support:
propertyMap.Add("as_billaddress", MyClass.GetProperty("BillAddress"));
// ...
}
You could then just do a dictionary lookup instead of using reflection in each call... This could also be setup fairly easy using configuration, so you could reconfigure the mappings at runtime.
A custom attribute seems like the best option to me - the framework seems to do this a lot as well (specifically with serialization).
If you look at popular ORM mappers then nearly all either use custom attributes or some kind of XML mapping file. The advantage of the latter is that you can modify the mapping without recompiling your application - the downside is that it hurts performance. However, I'd say your choice seems perfectly reasonable.

XmlDocument.Validate ignore properties without [XmlIgnore]

I have a object that has a number of properties that aren't present in the xsd file. When doing XmlDocument.Validate is there a way I can tell it to ignore properties that are not present in the xsd and instead just ensure that the properties required by xsd are present in the xml document?
I can get around this by adding [XmlIgnore] attributes all over my class but I would rather accomplish this by convention rather then explicitly add attributes all throughout my object model.
I doubt there is. Personally I would create a separate DTO, as it sounds like you're trying to make one object serve two jobs. Another option would be to use the XmlSerializer ctor that allows you to specify attribs at runtime, but this is much more work than [XmlIgnore].
So if you just want it to work: [XmlIgnore]. If you want it to be "pure", create a second DTO model and translate between them.

Categories