/// <summary>
 /// 复杂类型为键值对
 /// </summary>
 /// <param name="instance">实例</param>
 /// <param name="options">选项</param>
 /// <returns></returns>
 private IEnumerable <KeyValuePair <string, string> > FormatAsComplex(object instance, FormatOptions options)
 {
     return
         (from p in PropertyDescriptor.GetProperties(instance.GetType())
          where p.IsSupportGet && p.IgnoreSerialized == false
          let value = p.GetValue(instance)
                      let opt = options.CloneChange(p.DateTimeFormat)
                                select this.FormatAsSimple(p.AliasName, value, opt));
 }
 /// <summary>
 /// 数组为键值对
 /// </summary>
 /// <param name="name">名称</param>
 /// <param name="enumerable">值</param>
 /// <param name="options">选项</param>
 /// <returns></returns>
 private IEnumerable <KeyValuePair <string, string> > ForamtAsEnumerable(string name, IEnumerable enumerable, FormatOptions options)
 {
     return(from item in enumerable.Cast <object>()
            select this.FormatAsSimple(name, item, options));
 }
        /// <summary>
        /// 序列化对象为键值对
        /// </summary>
        /// <param name="name">对象名称</param>
        /// <param name="obj">对象实例</param>
        /// <param name="options">选项</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <returns></returns>
        public IEnumerable <KeyValuePair <string, string> > Serialize(string name, object obj, FormatOptions options)
        {
            if (options == null)
            {
                options = new FormatOptions();
            }

            var type       = obj == null ? null : obj.GetType();
            var descriptor = TypeDescriptor.GetDescriptor(type);

            if (descriptor == null || descriptor.IsSimpleType == true)
            {
                var kv = this.FormatAsSimple(name, obj, options);
                return(new[] { kv });
            }

            if (descriptor.IsDictionaryOfString == true)
            {
                var dic = obj as IDictionary <string, string>;
                return(this.FormatAsDictionary <string>(dic, options));
            }

            if (descriptor.IsDictionaryOfObject == true)
            {
                var dic = obj as IDictionary <string, object>;
                return(this.FormatAsDictionary <object>(dic, options));
            }

            if (descriptor.IsEnumerable == true)
            {
                var enumerable = obj as IEnumerable;
                return(this.ForamtAsEnumerable(name, enumerable, options));
            }

            return(this.FormatAsComplex(obj, options));
        }
 /// <summary>
 /// 序列化参数为键值对
 /// </summary>
 /// <param name="parameter">参数</param>
 /// <param name="options">选项</param>
 /// <returns></returns>
 public IEnumerable <KeyValuePair <string, string> > Serialize(ApiParameterDescriptor parameter, FormatOptions options)
 {
     return(this.Serialize(parameter.Name, parameter.Value, options));
 }
        /// <summary>
        /// 简单类型为键值对
        /// </summary>
        /// <param name="name">名称</param>
        /// <param name="value">值</param>
        /// <param name="options">选项</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <returns></returns>
        private KeyValuePair <string, string> FormatAsSimple(string name, object value, FormatOptions options)
        {
            if (string.IsNullOrEmpty(name) == true)
            {
                throw new ArgumentNullException(nameof(name));
            }

            if (options.UseCamelCase == true)
            {
                name = FormatOptions.CamelCase(name);
            }

            if (value == null)
            {
                return(new KeyValuePair <string, string>(name, null));
            }

            var isDateTime = value is DateTime;

            if (isDateTime == false)
            {
                return(new KeyValuePair <string, string>(name, value.ToString()));
            }

            // 时间格式转换
            var dateTime = ((DateTime)value).ToString(options.DateTimeFormat, DateTimeFormatInfo.InvariantInfo);

            return(new KeyValuePair <string, string>(name, dateTime));
        }
 /// <summary>
 /// 字典转换为键值对
 /// </summary>
 /// <param name="dic">字典</param>
 /// <param name="options">选项</param>
 /// <returns></returns>
 private IEnumerable <KeyValuePair <string, string> > FormatAsDictionary <TValue>(IDictionary <string, TValue> dic, FormatOptions options)
 {
     return(from kv in dic select this.FormatAsSimple(kv.Key, kv.Value, options));
 }