Где этот несериализуемый объект?

Я пытаюсь сериализовать объект, и возникает следующее исключение SerializationException:

Введите 'System.Linq.Enumerable + d__71`1 [[System.String, mscorlib, Version = 4.0.0.0, Culture = нейтральный, PublicKeyToken = b77a5c561934e089]]' в сборке 'System.Core, Version = 4.0.0.0, Culture = нейтральный, PublicKeyToken = b77a5c561934e089 'не помечен как сериализуемый.

Где этот объект в моем коде? Как мне узнать? Граф объекта довольно большой.


person SFun28    schedule 16.03.2011    source источник
comment
Это просто стек для сериализации ... ничего об объекте, который нельзя сериализовать   -  person SFun28    schedule 16.03.2011


Ответы (3)


Попробуйте использовать Reflector и посмотрите, сможете ли вы определить, где в вашем коде используется анонимный тип d__71`1.

person Mark Hurd    schedule 16.03.2011
comment
Благодарность! Я даже не подумал загрузить свою dll в рефлектор. Как только я это сделал, было легко найти d__71'1 и проанализировать его использование. Спасибо! - person SFun28; 16.03.2011

Мне кажется, что вы сохранили результаты вызова метода перечислителя без преобразования результата в список.

Когда у вас есть такой метод:

public IEnumerable<string> GetMyWidgetNames()
{
    foreach (var x in MyWidgets)
    { 
        yield return x.Name;
    }
}

Компилятор превращает это во вложенный объект с именем, подобным тому, которое вы видите (объект с именем, которое вы никогда не могли бы создать самостоятельно из-за встроенного +)

Если вы затем сохраните ссылку на этот объект внутри того, что пытаетесь сериализовать, вы получите исключение, отмеченное OP.

«Исправление» состоит в том, чтобы ваши сериализованные объекты всегда преобразовывали любые назначения IEnumerable ‹> в списки. Вместо этого

public IEnumerable<string> WidgetNames { get; set; }

вам нужно написать:

public IEnumerable<string> WidgetNames
{
    get { return mWidgetNames; }
    set
    {
        if (value == null)
            mWidgetNames= null
        else mWidgetNames= value.ToList();
    }
}
private List<string> mWidgetNames;
person Bevan    schedule 16.03.2011
comment
+1, System.Linq.Enumerable ... означает, что этот набор данных возвращается из запроса Linq. Хотя он реализует IEnumerable, его нельзя сериализовать. Обычно вам нужно вызвать ToList () или ToArray () для этого результата Linq, а затем его можно сериализовать. - person Lex Li; 16.03.2011
comment
это очень помогло. Я хочу ТАК позвольте мне разделить ответ. Ваш ответ вместе с @Mark Hurd помог мне отследить проблему. На самом деле это был объединенный объект IEnumerable, который нужно было выровнять в список. Я подбросил монетку, за кого наградить ответ. - person SFun28; 16.03.2011

Попробуйте сериализовать объект (одного типа) за раз и посмотреть, когда он взорвется. Вы можете сделать это вручную или через отражение.

person RQDQ    schedule 16.03.2011
comment
Так почему же голос против? Именно так я бы решил проблему (и у меня довольно хорошее предчувствие, что это сработает). - person RQDQ; 16.03.2011