2013-11-10 2 views
1

У меня есть ObservableCollection<Recipe> сохраненные как строка JSON в моем IsolatedStorageSettings.десериализация и объектные ссылки

Класс Recipe имеет поле под названием Category, который инициализируется с помощью этого кода:

[JsonProperty] 
private Category _category = RecipesViewModel.BaseCategories.First(); 

Category является чем-то вроде этого:

[JsonProperty] 
public Categories BaseCategory; 

/// <summary> 
///  Background picture for the cagtegory 
/// </summary> 
public string Picture 
{ 
    get { return string.Format(@"/Assets/CategoriesPictures/{0}.jpg", BaseCategory); } 
} 
/// <summary> 
///  Category's name 
/// </summary> 
public string Name 
{ 
    get { return BaseCategory.ToString(); } 
} 

/// <summary> 
///  List of recipes that belong to this category 
/// </summary> 
public IEnumerable<Recipe> Recipes 
{ 
    get { return App.ViewModel.GetRecipesByCategory(this); } 
} 

/// <summary> 
/// We need this to let everyone know that something may have been changed in our collections 
/// </summary> 
public void UpdateCategory() 
{ 
    RaisePropertyChanged(() => Recipes); 
} 

где BaseCategory является простой Enum

public enum Categories 
{ 
    Breakfast, 
    Lunch, 
    Appetizer, 
    Sidedish, 
    Soup, 
    Dessert, 
    Beverages 
} 

На данный момент я имею только один Recipe в моем ObservableCollection<Recipe>, и это JSON, который сохраняется в IsolatedStorageSettings:

[ 
    { 
    "_addedDate": "2013-11-10T19:08:00.8968706+01:00", 
    "_category": { 
     "BaseCategory": 2 
    }, 
    "_ingredients": [], 
    "_recipeName": "recipeName", 
    "_steps": [], 
    "_temperature": 0.0 
    } 
] 

BaseCategories объявлен

public static ReadOnlyCollection<Category> BaseCategories { get; private set; } 

и он строится по этому методу:

private static void BuildCategories() 
{ 
    var categories = new ObservableCollection<Category>(); 
    foreach (var enumValue in from category in typeof(Categories).GetFields() 
           where category.IsLiteral 
           select (Categories)category.GetValue(typeof(Categories))) 
    { 
     categories.Add(new Category { BaseCategory = enumValue }); 
    } 
    BaseCategories = new ReadOnlyObservableCollection<Category>(categories); 
} 

Что происходит, так это то, что во время моего метода загрузки данных первый элемент BaseCategories становится Category, который написан в JSON.

В этом случае он превращается из завтрака в Закуска (который является Category единственными сохранено Recipe).

Это код, который я использую, чтобы загрузить мои данные:

public void LoadData() 
{ 
    if (BaseCategories.IsEmpty()) 
     BuildCategories(); 
    // Load data from IsolatedStorage 
    var jsonString = ""; 
    if (IsolatedStorageSettings.ApplicationSettings.TryGetValue(RecipesKey, out jsonString)) 
    { 
     // BEFORE THIS LINE EVERYTHING IS FINE 
     Recipes = JsonConvert.DeserializeObject<ObservableCollection<Recipe>>(jsonString); 
     // AFTER THIS LINE, THE FIRST CATEGORY IN BaseCategories IS CHANGED 
    } 
    UpdateCategories(); 
    IsDataLoaded = true; 
} 

Кто-нибудь знает, что там происходит?

Я работаю над этим кодом весь день, так что голова уже ушла!

ответ

0

Кажется, очень знакомы с ASP.NET. О методе. Вы заметили, что переменная «jsonString» пуста? Вы пытаетесь получить что-то из сериализуемого json-объекта, тогда как «что-то» пусто. И попробуйте использовать явное преобразование типа в тип Recipce.

+0

«jsonString» var пуст, потому что он передается в качестве параметра 'out' в эту строку' if (IsolatedStorageSettings.ApplicationSettings.TryGetValue (RecipesKey, out jsonString)) ', который загружает его из' IsolatedStorage' – StepTNT

0

Прежде всего, я бы предложил использовать соответствующие атрибуты аннотации в вашей модели просмотра, используя: [DataContract] для всего объекта, [DataMember] для свойств, которые должны быть сериализованы, и [IgnoreDataMember] по свойствам, которые следует игнорировать от JSON.net.
Также класс Категории следует использовать стандартные свойства, которые инициализированы с соответствующими значениями в конкретном методе, вместо использования жестко закодированные добытчиков:

public Categories BaseCategory { get; set; } 
public string Picture { get; set; } 
public string Name { get; set; } 
public IEnumerable<Recipe> Recipes { get; set; } 

В вашем рецепте использование сериализовать BaseCategory и IgnoreDataMember Категории:

[DataMember] 
public Categories BaseCatagory { get; set; } 
[IgnoreDataMember] 
public Category Category { get; set; } 

Сообщите мне, если это поможет.

+0

I ' m, используя атрибут 'JsonProperty', потому что я пометил мои классы' [JsonObject (MemberSerialization.OptIn)] ', чтобы не добавлять' [IgnoreDataMember] 'в каждое поле. Я попробую использовать свойства, поскольку они должны использоваться, но я не уверен, что именно поэтому у меня есть эта странная проблема. – StepTNT

+0

Я просто попытался с вашими предложениями, но проблема не устранена. Когда строка десериализована, первая «категория» коллекции «BaseCategories» становится той, которая находится в десериализованном «Рецепте», и это довольно странно: \ – StepTNT

+0

Можете ли вы предоставить простой проект VS, где мы можем воспроизвести ошибку, с только необходимые классы? Благодарю. –

Смежные вопросы