Conversion Settings
Conversion settings control how JSON query result generated by call to one of the overloaded JsonQL.Query.IQueryManager.QueryObject<TQueriedObject>(…), (e.g., queryManager.QueryObject<IEmployee?[]>(…)) is converted to expected type instance.
This includes things like errors reported (or ignored) during conversion process or the expected format of JSON object keys (e.g., Pascal or camel case format for field names).
Conversion settings are setup once by configuring an instance of JsonQL.JsonToObjectConversion.IJsonConversionSettings that is injected into JsonQL.Query.QueryManager (normally done as part of dependency injection setup on application start).
All conversion settings in JsonQL.JsonToObjectConversion.IJsonConversionSettings can be overridden using optional parameter jsonConversionSettingOverrides of type JsonQL.JsonToObjectConversion.IJsonConversionSettingsOverrides used in calls to one of the overloaded JsonQL.Query.IQueryManager.QueryObject<TQueriedObject>(…).
Code snippet example demonstrating configuring JsonQL.JsonToObjectConversion.IJsonConversionSettings.
private static IJsonConversionSettings CreateConversionSettings()
{
var conversionErrorTypeConfigurations = new List<ConversionErrorTypeConfiguration>();
foreach (var conversionErrorType in Enum.GetValues<ConversionErrorType>())
{
// Set custom ErrorReportingType for ConversionErrorType here.
// We report all errors as ErrorReportingType.ReportAsError by default.
conversionErrorTypeConfigurations.Add(new ConversionErrorTypeConfiguration(conversionErrorType, ErrorReportingType.ReportAsError));
}
return new JsonConversionSettings
{
JsonPropertyFormat = JsonPropertyFormat.PascalCase,
FailOnFirstError = true,
ConversionErrorTypeConfigurations = conversionErrorTypeConfigurations,
// Set custom interface to implementation mappings here.
// Default mapping mechanism (i.e., IModelClassMapper) will
// try to find an implementation that has the same name space and class
// name that matches interface name without "I" prefix (if the mapped
// type defaultTypeToConvertParsedJsonTo is an interface).
// For example for interface JsonQL.Demos.Examples.DataModels.IEmployee class
// JsonQL.Demos.Examples.DataModels.Employee will be used if it exists and it
// implements JsonQL.Demos.Examples.DataModels.IEmployee.
// If defaultTypeToConvertParsedJsonTo is a class, the default mapping mechanism will
// use the class itself.
TryMapJsonConversionType =
(defaultTypeToConvertParsedJsonTo, convertedParsedJson) =>
{
if (defaultTypeToConvertParsedJsonTo == typeof(IEmployee))
{
if (convertedParsedJson.HasKey(nameof(IManager.Employees)))
return typeof(IManager);
if (!convertedParsedJson.HasKey(nameof(Employee.Id)))
return typeof(EmployeeWithoutId);
}
// Returning null will result default mapping mechanism picking a type to use.
return null;
}
};
}
Code snippet example demonstrating overriding some settings configured in JsonQL.JsonToObjectConversion.IJsonConversionSettings for a specific query execution using optional parameter jsonConversionSettingOverrides of type JsonQL.JsonToObjectConversion.IJsonConversionSettingsOverrides.
// Select the employees in all companies with non-null value for Address
var query =
"Companies.Select(c => c.Employees).Where(e => e.Address is not null)";
// Set the value of queryManager to an instance of JsonQL.Query.IQueryManager here.
// The value of JsonQL.Query.IQueryManager is normally created by Dependency Injection container
// and it is normally configured as a singleton.
JsonQL.Query.IQueryManager queryManager = null!;
var employeesResult = queryManager.QueryObject<IReadOnlyList<IEmployee>>(query,
new JsonTextData("Companies",
LoadJsonFileHelpers.LoadJsonFile("Companies.json",
["DocFiles", "QueryingJsonFiles", "JsonFiles"])),
jsonConversionSettingOverrides: new JsonConversionSettingsOverrides
{
// Lets report nullable values not set errors as warnings. The other errors not specified in
// ConversionErrorTypeConfigurations will use the values set in
// JsonQL.JsonToObjectConversion.IJsonConversionSettings
ConversionErrorTypeConfigurations = new List<IConversionErrorTypeConfiguration>
{
new ConversionErrorTypeConfiguration(ConversionErrorType.NonNullablePropertyNotSet, ErrorReportingType.ReportAsWarning),
new ConversionErrorTypeConfiguration(ConversionErrorType.NonNullablePropertyNotSet, ErrorReportingType.ReportAsWarning),
new ConversionErrorTypeConfiguration(ConversionErrorType.ValueNotSet, ErrorReportingType.ReportAsWarning)
},
FailOnFirstError = false,
TryMapJsonConversionType = (defaultTypeToConvertParsedJsonTo, convertedParsedJson) =>
{
if (defaultTypeToConvertParsedJsonTo == typeof(Employee) &&
convertedParsedJson.HasKey(nameof(IManager.Employees)) &&
!(convertedParsedJson.TryGetJsonKeyValue(nameof(IManager.Employees), out var employees) &&
employees.Value is IParsedArrayValue employeesArray &&
employeesArray.Values.Count > 0))
{
return typeof(ManagerWithoutEmployees);
}
// Returning null will result in configuration setup in
// JsonQL.JsonToObjectConversion.IJsonConversionSettings being used.
return null;
}
});