Я пытаюсь написать собственный JavascriptConverter для использования с веб-сервисом, который я пишу. Мне нужно написать собственный конвертер, потому что Microsoft.JScript.JSObject не поддерживает IDictionary, поэтому он рассматривается как массив. У меня эта часть работает нормально. Однако, поскольку Microsoft.JScript.ArrayObject является подклассом Microsoft.JScript.JSObject, он также пытается преобразовать его, используя тот же метод. Как я могу вернуть то, что будет сериализовано как массив JSON? Я должен вернуть IDictionary, который станет объектом JSON. Я что-то упускаю?
В частности, как я могу вернуть что-то из Serialize, которое сериализуется как массив, а не как объект.
Спасибо!
EDIT:
Полагаю, мне нужно быть более конкретным.
Microsoft.JScript.JSObject реализует IEnumerable, но не IDictionary. Microsoft.JScript.ArrayObject является подклассом Microsoft.JScript.JSObject. Если я создаю .asmx в JScript.NET, когда я пытаюсь вернуть JSObject, он сериализуется как массив (потому что он реализует IEnumerable, но не IDictionary), что означает, что сериализуются только имена свойств в объекте. Конечно, если я возвращаю ArrayObject, он работает правильно и сериализует его как массив.
Итак, я реализовал подкласс JavascriptConverter, который говорит, что его SupportedType - Microsoft.JScript.JSObject. Теперь JSObjects правильно сериализованы. Однако, поскольку ArrayObject является подклассом JSObject, JavascriptSerializer больше не заботится о сериализации самого ArrayObjects, он передает его сериализатору JSObject. Вопрос в том, как мой собственный сериализатор возвращает что-то, что JavaScriptSerializer будет правильно обрабатывать как массив, а не как объект - Serialize вынужден возвращать IDictionary, и это сериализуется как объект, а не массив.
Имеет ли этот вопрос больше смысла?
Кстати: я вместо этого посмотрел на WCF и C #, но вывод DataContractJsonSerializer совершенно бесполезен, если только вы не собираетесь когда-либо получать к нему доступ только с помощью клиента WCF; Я планирую получить его с помощью jQuery.
Ответ:
Я наконец понял, что bdukes пытался сказать, и это работает! Вы должны сказать, что это массив при возврате словаря (хотя это не сработает для массива верхнего уровня). Вот функция Serialize
, которую я бы написал:
public override IDictionary<string, object> Serialize (object obj, JavaScriptSerializer serializer) {
JSObject jsobj = obj as JSObject;
Dictionary<string, object> netdict = new Dictionary<string, object>();
if (jsobj != null) {
foreach (string prop in jsobj) {
object value = jsobj.GetField(prop, BindingFlags.Default).GetValue(jsobj);
switch (value.GetType().FullName) {
case "Microsoft.JScript.ArrayObject":
object[] arr_obj = ((IEnumerable)(Microsoft.JScript.ArrayObject)value).Cast<object>().ToArray<object>();
netdict.Add(prop, arr_obj);
break;
default:
netdict.Add(prop, value);
break;
}
}
}
return netdict;
}