Exemplo n.º 1
0
        private static string FormatGraphQLValue(object value, int depth = 0)
        {
            // some types require recursion as they can't be directly
            // converted. There is a maximum depth we're using to avoid stack
            // overflow. For null values we just return an empty string.
            if (value == null || depth > MAX_RECURSION_DEPTH)
            {
                return(@"");
            }

            // string is probably the most common one.
            // for strings, we need to add " and escape quotes.
            if (value is string)
            {
                string input  = (string)value;
                string output = string.Concat("\"", input.Replace("\"", "\\\""), "\"");
                return(output);
            }

            // GUIDs are a special type of string
            if (value is Guid)
            {
                Guid   input  = (Guid)value;
                string output = string.Concat("\"", input.ToString(), "\"");
                return(output);
            }

            // boolean are expected to be lower case.
            if (value is bool?)
            {
                bool?input = (bool?)value;

                if (input.HasValue)
                {
                    string output = input.ToString().ToLowerInvariant();
                    return(output);
                }

                return("");
            }

            // boolean are expected to be lower case.
            if (value is bool)
            {
                bool   input  = (bool)value;
                string output = input.ToString().ToLowerInvariant();
                return(output);
            }

            // DateTime values are expected to be in JSON format.
            if (value is DateTime)
            {
                DateTime input  = (DateTime)value;
                string   output = string.Concat("\"", input.ToString("yyyy-MM-ddTHH:MM:ss.sssZ"), "\"");
                return(output);
            }

            // numbers can be directly converted using their internal to string.
            if (value is ValueType)
            {
                if (value is byte ||
                    value is short ||
                    value is int ||
                    value is long ||
                    value is sbyte ||
                    value is ushort ||
                    value is uint ||
                    value is ulong ||
                    value is float ||
                    value is double ||
                    value is decimal)
                {
                    string output = value.ToString();
                    return(output);
                }
            }

            // enumerations can be directly converted. This only works if the
            // enumeration in C# is named exactly as in the GraphQL API.
            if (value is Enum)
            {
                string output = value.ToString();
                return(output);
            }

            // for arrays we don't care about the array's child types as they
            // will be handled by a recursive function
            if (value is Array)
            {
                IEnumerable input = value as IEnumerable;

                List <string> inputList = new List <string>();
                foreach (object element in input)
                {
                    string fValue = FormatGraphQLValue(element, depth + 1);

                    // exclude empty values (strings that are of length 0.
                    // note that if the parameter supplies an empty string,
                    // it will actually be '\"\"' that is returned by
                    // FormatGraphQLValue, so this still works
                    if (string.IsNullOrEmpty(fValue))
                    {
                        continue;
                    }

                    inputList.Add(fValue);
                }

                // create an output string. We don't need to handle the case
                // where inputList length is 0 as string.Join does that for us.
                string output = string.Concat(@"[", string.Join(@",", inputList), @"]");
                return(output);
            }

            // for GraphQLParameters we also need to apply recursion. If the
            // rest of the code is adhering to a standard, this should only be
            // called once and the recursion is not needed.
            if (value is GraphQLParameters)
            {
                GraphQLParameters input = (GraphQLParameters)value;

                string output = string.Concat(@"{", input.ToString(), @"}");
                return(output);
            }

            // here we format every remaining object type. We recursively
            // include every property that has the JsonPath attribute defined.
            PropertyInfo[] properties = JsonPath.GetJsonPathProperties(value);

            if (properties.Length > 0)
            {
                List <string> inputList = new List <string>();

                foreach (PropertyInfo property in properties)
                {
                    // this will return the first attribute matching. We don't
                    // need to check for null as the properties list is already
                    // filtered for only properties with the JsonPath attribute.
                    JsonPath attr = JsonPath.GetJsonPathAttribute(property);

                    // try formatting the value. If it is null, we won't add it
                    // to the parameter list.
                    string fValue = FormatGraphQLValue(property.GetValue(value), depth + 1);
                    if (string.IsNullOrEmpty(fValue))
                    {
                        continue;
                    }

                    string element = string.Concat(attr.BasePath, @":", fValue);
                    inputList.Add(element);
                }

                // if there are no property values set, we consider this an
                // empty parameter set and we return an empty string.
                if (inputList.Count == 0)
                {
                    return(@"");
                }

                string output = string.Concat(@"{", string.Join(@",", inputList), @"}");
                return(output);
            }

            // Catch all. We should not reach this.
            throw new NebException("unsupported object type supplied");
        }