I have a JSON string. I want to check if it contains an anonymous object. If it does then return the value. If it doesn't then return a default value. I then want to be able to repeat this multiple times for different anonymous objects.
Here is a sample of the code that I have currently implemented but obviously it is duplicated each time and not very "clean".
var displayDataBy = 0;
var displayDataByDefinition = new { DisplayDataBy = new { Key = "string", Value = displayDataBy } };
var displayDataByResult = JsonConvert.DeserializeAnonymousType(this.OhdContentPageParameters, displayDataByDefinition);
try { displayDataBy = displayDataByResult.DisplayDataBy.Value; }
catch { }
var xMinsOeeToShow = 480;
var xMinsOeeToShowDefinition = new { XMinsOeeToShow = new { Key = "string", Value = xMinsOeeToShow } };
var xMinsOeeToShowResult = JsonConvert.DeserializeAnonymousType(this.OhdContentPageParameters, xMinsOeeToShowDefinition);
try { xMinsOeeToShow = xMinsOeeToShowResult.XMinsOeeToShow.Value; }
catch { }
I would prefer it was a generic method that I could call for each anonymous type. Also it would be nice to not have to rely on the try/catch. Can it be done?
UPDATE...
This is working great for int, bool and double:
public static T2 DeserializeValue<T, T2>(this string json, T definition, T2 defaultValue, Func<T, T2?> getValueFunc) where T2 : struct
{
var jsonAnon = JsonConvert.DeserializeAnonymousType(json, definition);
return getValueFunc(jsonAnon) ?? defaultValue;
}
I added this for strings:
public static string DeserializeStringValue<T>(this string json, T definition, string defaultValue, Func<T, string> getValueFunc)
{
var jsonAnon = JsonConvert.DeserializeAnonymousType(json, definition);
return getValueFunc(jsonAnon) ?? defaultValue;
}
Using a helper class to generalize the operations you are performing,
public static class DeserializeHelpers {
public static T2 DeserializeValue<T,T2>(this string s, T def, T2 defans, Func<T, T2?> getAnsFn) where T2 : struct {
var jsonAnon = JsonConvert.DeserializeAnonymousType(s, def);
return getAnsFn(jsonAnon) ?? defans;
}
public static T2 DeserializeClass<T,T2>(this string s, T def, T2 defans, Func<T, T2> getAnsFn) where T2 : class {
var jsonAnon = JsonConvert.DeserializeAnonymousType(s, def);
return getAnsFn(jsonAnon) ?? defans;
}
}
You can slightly simplify your code as follows. I left in some of the verbose coding as you seemed to be going to great lengths to avoid putting in an explicit type for Value
but I was forced to assume it was a value type to allow for null
returns from the member accessor lambda. If a class might be returned, you would need to use the class helper.
var displayDataBy = 0;
var displayDataByDefinition = new { DisplayDataBy = new { Key = "string", Value = displayDataBy } };
var displayDataByResult = this.OhdContentPageParameters.DeserializeValue(displayDataByDefinition, displayDataBy, x => x.DisplayDataBy?.Value);
var xMinsOeeToShow = 480;
var xMinsOeeToShowDefinition = new { XMinsOeeToShow = new { Key = "string", Value = xMinsOeeToShow } };
var xMinsOeeToShowResult = this.OhdContentPageParameters.DeserializeValue(xMinsOeeToShowDefinition, xMinsOeeToShow, x => x.XMinsOeeToShow?.Value);
I used an extension method for Deserialize...
but of course it could be a regular method.
If you don't need to reuse the anonymous type definition you could pass that inline to the Deserialize...
method.