2013-05-20 2 views
1

У меня есть код следующим образом внутри метода:Null ссылка на класс Cache вопрос

var currency = new Dictionary<string, List<Currency>>(); 

if (Cache["Currency"] == null) 
{ 
    //here I fill currency with data and then set it to Cache. 
    Cache["Currency"] = currency ; 
} 
else 
{ 
    var currency = Cache["Currency"] as Dictionary<string, List<Currency>>; 
    //here I am getting null reference exception: 
    foreach (var item in currency) 
} 

Я прочитал, что класс кэша не должен использоваться непосредственно из приложения, но что такое правильное использование класса Cache в моем случае?

EDIT: Я отправляю весь мой код:

protected void DisplayCurrency() 
{ 
    Dictionary<string, List<Currency>> currList = new Dictionary<string, List<Currency>>(); 

    if (Cache["Currency"] == null) 
    { 
     var xmlDoc = XElement.Load("http://www.tcmb.gov.tr/kurlar/today.xml"); 
     if (xmlDoc != null) 
     { 
      var queryXML = from xml in xmlDoc.Elements("Currency") 
          where (string)xml.Attribute("Kod") == "USD" || (string)xml.Attribute("Kod") == "EUR" 
          select xml; 

      if (queryXML != null) 
      { 
       //fill Dictionary with data 
       foreach (var item in queryXML) 
       { 
        currList.Add(item.Attribute("Kod").Value, new List<Currency> 
         { 
          new Currency 
           {  
            ForexBuying = item.Element("ForexBuying").Value, 
            ForexSelling = item.Element("ForexSelling").Value, 
            BanknoteBuying = item.Element("BanknoteBuying").Value, 
            BanknoteSelling= item.Element("BanknoteSelling").Value 
           } 
         }); 
       } 
       //Cache["Currency"] = currList; 
       HttpContext.Current.Cache["Currency"] = currList; 

       //read data from Dictionary instance 
       foreach (var item in currList) 
       { 
        switch (item.Key) 
        { 
         case "USD": 
          litUSDtxt.Text = item.Key; 
          foreach (var i in item.Value) 
          { 
           litUSD.Text = i.BanknoteSelling; 
          } 
          break; 

         case "EUR": 
          litEURtxt.Text = item.Key; 
          foreach (var i in item.Value) 
          { 
           litEUR.Text = i.BanknoteSelling; 
          } 
          break; 
        } 
       } 
      } 
     } 
     // Cache.Insert("Currency", currList, null, DateTime.Now.AddDays(1), TimeSpan.Zero); 
    } 
    else 
    { 
     var currency = Cache["Currency"] as Dictionary<string, List<Currency>>; 
     foreach (var item in currency) 
     { 
      switch (item.Key) 
      { 
       case "USD": 
        litUSDtxt.Text = item.Key; 
        foreach (var i in item.Value) 
        { 
         litUSD.Text = i.BanknoteSelling; 
        } 
        break; 

       case "EUR": 
        litEURtxt.Text = item.Key; 
        foreach (var i in item.Value) 
        { 
         litEUR.Text = i.BanknoteSelling; 
        } 
        break; 
      } 
     } 
    } 

} 


class Currency 
{ 
    public string ForexBuying { get; set; } 
    public string ForexSelling { get; set; } 
    public string BanknoteBuying { get; set; } 
    public string BanknoteSelling { get; set; } 
} 
+0

Вы ссылались на эту ссылку: http://msdn.microsoft.com/en-us/library/18c1wd61(v=vs.100).aspx – Saravanan

+1

, что вы храните в 'Cache [" Currency "] = someObject' line. я.e someobject имеет тип –

+0

, кажется, что объект в 'Cache [" Currency "]' не имеет типа 'Dictionary >' – ppetrov

ответ

3

Первые несколько пунктов:

  1. НЕ инициализировать currency каждый раз. Это пустая трата времени, когда кеш уже содержит экземпляр.
  2. Никогда не пытайтесь проверить, есть ли что-то в кеше, и получить его двумя разными шагами. Между этими шагами кеш мог быть очищен процессом anohter, создав NullReferenceException.
  3. В своем первом редактировании вашего вопроса вы помещаете в кэш другой объект. Проверьте свое программное обеспечение в другом месте. Если ANYWHERE в вашем коде Cache["Currency"] заполняется объектом типа anohter, операция as всегда будет возвращать null.

Ваш код должен выглядеть следующим образом:

var currency = Cache["Currency"] as Dictionary<string, List<Currency>>; 
if (currency == null) 
{ 
    currency = new Dictionary<string, List<Currency>>(); 
    // At this point, initialize currency, fill it with data from your XML file, or whatever. 
    Cache["Currency"] = currency; 
} 
// At this point, currency is loaded from cache or recreated. Now you can use it to fill your controls, variables, etc. 

Или ... в revice весь код:

protected void DisplayCurrency() 
{ 
    var currency = Cache["Currency"] as Dictionary<string, List<Currency>>; 

    if (currency == null) 
    { 
     currency = new Dictionary<string,List<Currency>>(); 
     var xmlDoc = XElement.Load("http://www.tcmb.gov.tr/kurlar/today.xml"); 
     if (xmlDoc != null) 
     { 
      var queryXML = from xml in xmlDoc.Elements("Currency") 
          where (string)xml.Attribute("Kod") == "USD" || (string)xml.Attribute("Kod") == "EUR" 
          select xml; 

      if (queryXML != null) 
      { 
       //fill Dictionary with data 
       foreach (var item in queryXML) 
       { 
        currency.Add(item.Attribute("Kod").Value, new List<Currency> 
        { 
         new Currency 
         {  
          ForexBuying = item.Element("ForexBuying").Value, 
          ForexSelling = item.Element("ForexSelling").Value, 
          BanknoteBuying = item.Element("BanknoteBuying").Value, 
          BanknoteSelling= item.Element("BanknoteSelling").Value 
         } 
        }); 
       } 
      } 
     } 
     Cache["Currency"] = currency; 
    } 
    foreach (var item in currency) 
    { 
     switch (item.Key) 
     { 
      case "USD": 
       litUSDtxt.Text = item.Key; 
       foreach (var i in item.Value) 
       { 
        litUSD.Text = i.BanknoteSelling; 
       } 
       break; 

      case "EUR": 
       litEURtxt.Text = item.Key; 
       foreach (var i in item.Value) 
       { 
        litEUR.Text = i.BanknoteSelling; 
       } 
       break; 
     } 
    } 
} 
+0

Да, согласился +1 от меня :) –

+0

решает проблему OP ?? –

+0

@ RajeevKumar Не могу, но это всего лишь правильный способ сделать это в целом. –

0
var currency = Cache["Currency"] as Dictionary<string, List<Currency>>; 

Очевидно, что приведение не удалось, и currency равна нулю (Это правильное поведение, если преобразование не представляется возможным). Вы должны проверить, если это null:

if (currency != null) { 
    foreach(var item in currency) { 

    } 
} 

http://msdn.microsoft.com/en-us/library/cscsdfbt.aspx

0

Я думаю, что вы устанавливаете его к неправильной переменной, она не должна быть:

Cache["Currency"] = currency; 

вместо:

Cache["Currency"] = someObject; 

Или в случае, если вы действительно имели в виду использовать someObject убедитесь, что он имеет тип Dictionary<string, List<Currency>>, иначе as вернет null.

EDIT

Убедитесь, что вы используете HttpContext.Cache, это общая проблема:

HttpContext.Cache["Currency"] = currency; 
+0

Я установил его в валюту. Нет ошибки –

+0

@ black123 в вашем примере это 'someObject', вы должны убедиться, что' someObject' - это тот же тип, что и тот, который вы используете, иначе вы получите 'null' –

+0

Правильно, это моя ошибка в проводке кода. Он настроен на валюту. –

0

Привет попробовать отладить еще часть с помощью следующего кода

else 
{ 
    currrency = Cache["Currency"] ; 
//here I am getting null reference exception: 
foreach (var item in currency) 
} 
+0

дайте мне знать, если вы все еще получаете var curr null –

+0

Вы попробовали запустить этот код. Я просто хочу знать, не проблема ли в вашем коде –

+0

Если я использую его таким образом, я не могу перебирать данные. Посмотрите на мой полный код. Спасибо –

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