private Expression GetXDocumentReaderProxy(IBindingValueInfo valueInfo)
        {
            MethodInfo parseInfo = typeof(XDocument).GetMethod("Parse", new[] { typeof(string) });

            Expression value       = valueInfo.Value;
            Expression stringValue = value.Type == typeof(string) ? value : Expression.Convert(value, typeof(string));
            Expression isNull      = Expression.ReferenceEqual(valueInfo.Value, Expression.Constant(null));
            Expression parseXml    = Expression.Call(parseInfo, stringValue);

            return(Expression.Condition(isNull, Expression.Default(typeof(XDocument)), parseXml));
        }
        private Expression GetValueReaderProxy(IBindingValueInfo valueInfo)
        {
            Expression value = valueInfo.Value;

            if (value.Type != typeof(object) && value.Type != typeof(string))
            {
                throw BindingException.Create(valueInfo.Metadata, $"Cannot deserialize JSON from type '{value.Type.GetSanitizedName()}'.");
            }

            Expression nullCheck = null;

            if (valueInfo.CanBeDbNull)
            {
                nullCheck = Expression.TypeIs(value, typeof(DBNull));
            }

            if (valueInfo.CanBeNull)
            {
                Expression isNull = Expression.ReferenceEqual(value, Expression.Constant(null, value.Type));

                nullCheck = nullCheck == null ? isNull : Expression.AndAlso(nullCheck, isNull);
            }

            if (value.Type == typeof(object))
            {
                value = Expression.Convert(value, typeof(string));
            }

            Expression targetValue;

            if (valueInfo.TargetType == typeof(JsonDocument))
            {
                targetValue = this.GetParseDocumentExpression(valueInfo.Metadata, value);
            }
            else if (valueInfo.TargetType == typeof(JsonElement))
            {
                targetValue = this.GetParseElementExpression(valueInfo.Metadata, value);
            }
            else
            {
                targetValue = this.GetDeserializeExpression(valueInfo.Metadata, value, valueInfo.Helper);
            }

            if (nullCheck != null)
            {
                return(Expression.Condition(nullCheck, Expression.Default(targetValue.Type), targetValue));
            }

            return(targetValue);
        }
        private Expression GetValueReaderProxy(IBindingValueInfo valueInfo)
        {
            Expression value = valueInfo.Value;

            if (value.Type != typeof(object) && value.Type != typeof(string))
            {
                throw BindingException.FromMetadata(valueInfo.Metadata, $"Cannot deserialize JSON from type '{value.Type.GetSanitizedName()}'.");
            }

            Expression nullCheck = null;

            if (valueInfo.CanBeDbNull)
            {
                nullCheck = Expression.TypeIs(value, typeof(DBNull));
            }

            if (valueInfo.CanBeNull)
            {
                Expression isNull = Expression.ReferenceEqual(value, Expression.Constant(null, value.Type));

                if (nullCheck == null)
                {
                    nullCheck = isNull;
                }
                else
                {
                    nullCheck = Expression.AndAlso(nullCheck, isNull);
                }
            }

            if (value.Type == typeof(object))
            {
                value = Expression.Convert(value, typeof(string));
            }

            Expression jsonValue = this.GetJsonDeserializer(valueInfo.Metadata, value, valueInfo.Helper);

            if (nullCheck != null)
            {
                return(Expression.Condition(nullCheck, Expression.Default(jsonValue.Type), jsonValue));
            }

            return(jsonValue);
        }