public static void WriteQueryString(TextWriter writer, object value) { try { JsState.QueryStringMode = true; var i = 0; foreach (var propertyWriter in PropertyWriters) { var propertyValue = propertyWriter.GetterFn((T)value); if (propertyValue == null) { continue; } if (i++ > 0) { writer.Write('&'); } var propertyType = propertyValue.GetType(); var strValue = propertyValue as string; var isEnumerable = strValue == null && !(propertyType.IsValueType()) && propertyType.HasInterface(typeof(IEnumerable)); if (QueryStringSerializer.ComplexTypeStrategy != null && !isEnumerable && (propertyType.IsUserType() || propertyType.IsInterface())) { if (QueryStringSerializer.ComplexTypeStrategy(writer, propertyWriter.PropertyName, propertyValue)) { continue; } } Serializer.WritePropertyName(writer, propertyWriter.PropertyName); writer.Write('='); if (strValue != null) { writer.Write(strValue.UrlEncode()); } else if (!isEnumerable) { propertyWriter.WriteFn(writer, propertyValue); } else { //Trim brackets in top-level lists in QueryStrings, e.g: ?a=[1,2,3] => ?a=1,2,3 using (var ms = MemoryStreamFactory.GetStream()) { var enumerableWriter = new StreamWriter(ms); //ms disposed in using propertyWriter.WriteFn(enumerableWriter, propertyValue); enumerableWriter.Flush(); var output = ms.ToArray().FromUtf8Bytes(); output = output.Trim(ArrayBrackets); writer.Write(output); } } } } finally { JsState.QueryStringMode = false; } }