I’ve already looked into a lot of the posts on SO of people having similar problems, but nothing has worked so far.
I have an two instances of an object. One is being used in another class, while the other one is being periodically (about every 5 seconds or so) updated with new information via websocket.
The first response from the websocket upon subscription is the object with all of it’s properties assigned a value. The problem is that the subsequent data coming in the from websocket only brings in data that has changed, so when I go to deserialize, it sets those properties that weren’t assigned a value, their default value.
I’d rather not have to do a “.ForMember” on each of the properties since this object has 52 of them.
var configuration = new MapperConfiguration(cfg =>
{
cfg.CreateMap<StreamingQuoteResponse.Content, StreamingQuoteResponse.Content>().ForAllMembers(opts => opts.Condition((src, dest, srcMember) => srcMember != null));
});
var mapper = new Mapper(configuration);
var newQuote = mapper.Map<StreamingQuoteResponse.Content>(quote);
As far as I can tell, in the above code, only the strings would be null by default. Floats would be 0; doubles, 0.0d, etc.
The object has all different types of properties (bool, double, float, char, string). Is there a way to ignore mapping of a single property if the source property is the default value? I was thinking there was a way to get the property type using AutoMapper’s (Pre)Condition, and then if it’s e.g. typeof(float), then we can ignore mapping if the source value is 0? I’m not sure if you can do that though.
Or maybe a subroutine/method that would resolve all of this using Reflections?
This might help someone in the future, but I ended up ditching the AutoMapper, and going with JSON.NET. I didn’t know they had this ‘JsonMergeSettings’. I also had to add an attribute to all the properties of the class I’m (de)serializing. For example:
public class Content
{
[JsonProperty("key", DefaultValueHandling = DefaultValueHandling.Ignore)]
public string Key { get; set; }
}
Then in the event handler that was receiving all the websocket data, I did the following:
private bool firstFlag = true;
private JObject jObject;
private void HandleStreamingWebsocketData(object sender, MessageEventArgs e)
{
if (firstFlag)
{
jObject = JObject.Parse(e.Data);
firstFlag = false;
}
jObject.Merge(JObject.Parse(e.Data), new JsonMergeSettings
{
MergeArrayHandling = MergeArrayHandling.Merge
});
}
Hopefully this helps someone trying to do the same thing. And I’m sure it can be done with AutoMapper, but this was much easier I think, and most likely a bit faster, since you’re merging the JSON before it’s being deserialized into a C# object, as opposed to deserializing the updated data and comparing it to the deserialized previous data, and the mapping them that way.