2

上で実行時バインディングを実行することはできません私はこのコードからCannot perform runtime binding on a null referenceエラーを引き起こしているかを把握しようとしている:MVC5/C#は - null参照

var query = "SELECT Id, UserName, List_Order, LoggedIn " + 
      "FROM AspNetUsers" + 
      "WHERE LoggedIn = 1" + 
      "ORDER BY List_Order ASC"; 

var conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString); 
var cmd = new SqlCommand(query, conn); 
conn.Open(); 
var rdr = cmd.ExecuteReader(); 
var n = 0; 
while(rdr.Read()) 
{ 
    if (Convert.ToString(rdr["UserName"]) != null) 
    { 
     ViewBag.speakers[n] = new string[4] { 
      Convert.ToString(rdr["Id"]), 
      Convert.ToString(rdr["UserName"]), 
      Convert.ToString(rdr["List_Order"]), 
      Convert.ToString(rdr["LoggedIn"]) 
     }; 

     //Exception Details: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot 
     //perform runtime binding on a null reference 
     n++; 
    } 
} 

n++増分は、このエラーの原因のようですし、なぜか分からない。

可能な解決策を反映するようにコードが更新されました。ただし、エラーは依然として残ります。ヌル列値に.ToString()方法はCannot perform runtime binding on a null referenceをもたらすことができる呼び出す

if (!string.IsNullOrWhiteSpace(Convert.ToString(rdr["UserName"]))) { 
     List<string> speakers = new List<string>(); 
     speakers.Add(Convert.ToString(rdr["Id"])); 
     speakers.Add(Convert.ToString(rdr["UserName"])); 
     speakers.Add(Convert.ToString(rdr["List_Order"])); 
     speakers.Add(Convert.ToString(rdr["LoggedIn"])); 

     ViewBag.speakers[n] = speakers; 
     n++; 
} 
+0

チェックアウト[この同様のポスト](http://stackoverflow.com/questions/28235162/cannot -perform-runtime-binding-on-a-null-reference-empty-excel-cells) –

+0

@LuisLavieriコードを更新しましたが、エラーはまだ表示されます。 –

+0

'if'も更新しましたか?今度は次のようになります: 'if(!string.IsNullOrWhiteSpace(Convert.ToString(rdr [" UserName "])))' –

答えて

2

二つの問題は、あなたのコードにあります。

public ActionResult Index() 
{ 
    int n = 0; 
    ViewBag.speakers[n] = 5; 
    return View(); 
} 

スピーカーが(ヌル参照)が定義されていないので、このコードの単純化された作品は、Cannot perform runtime binding on a null referenceをスロー:

が、この考えてみましょう。

あなたは、ループの前ダイナミック ViewBagでspeakersを定義することによって、それを修正することができます:

ViewBag.speakers = new List<string>(); 

第二の問題:

ViewBag.speakers[n] = speakers; 

スピーカーコード内でリストされ、あなたが望むかもしれませんViewBag.speakersList<List<string>>と定義し、インデックスを使用してアクセスする代わりに.Add(speakers)と呼び出してください(のインデックスが範囲外です)

2

は同じ結果でこれを試してみました。代わりにConvert.ToString()を使用してください。 nullの値を変換しようとすると空の文字列が返され、nullチェックのための追加コードは必要ありません。

+0

それは覚えておくべき素晴らしいトリックです。私は 'possiblyNull ?ToString()?? string.Empty' – Gusdor

+0

'Convert.ToString'メソッドを試しましたが、同じエラーが発生しました。 –

+0

@Danielあなたはどこかで 'スピーカー'をインスタンス化しましたか? –

1

ViewBagは動的オブジェクトであり、そのプロパティへの割り当てを実行しようとすると、実行時にnullチェックが行われます。 ViewBag.speakersがnullの場合、またはnthスロットにインデクサー(おそらくサイズがn未満、またはインデクサーがまったく定義されていない可能性があります)にアクセスしようとしているときに例外がスローされるため、このエラーが発生します。要素を追加する前にViewBag.speakersを初期化する必要があります。

var query = "SELECT Id, UserName, List_Order, LoggedIn " + 
      "FROM AspNetUsers" + 
      "WHERE LoggedIn = 1" + 
      "ORDER BY List_Order ASC"; 

var conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString); 
var cmd = new SqlCommand(query, conn); 
conn.Open(); 
var rdr = cmd.ExecuteReader(); 
ViewBag.speakers = new List<string[]>(); 
while(rdr.Read()) 
{ 
    if (Convert.ToString(rdr["UserName"]) != null) 
    { 
     var speakers = new string[4] { 
      Convert.ToString(rdr["Id"]), 
      Convert.ToString(rdr["UserName"]), 
      Convert.ToString(rdr["List_Order"]), 
      Convert.ToString(rdr["LoggedIn"]) 
     }; 
     ViewBag.speakers.Add(speakers); 
    } 
} 
0

あなたの問題は、ビュー側の実行時バインディング例外をスローするのに十分なその特定の時点で動的オブジェクトViewBag.speakersにnull参照を与えるExecuteReaderRead方法、使用方法の由来と思われます。

var query = "SELECT Id, UserName, List_Order, LoggedIn " + 
      "FROM AspNetUsers" + 
      "WHERE LoggedIn = 1" + 
      "ORDER BY List_Order ASC"; 

using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString)) 
{ 
    using (var cmd = new SqlCommand(query, conn)) 
    { 
     conn.Open(); 
     var dt = new DataTable(); 
     ViewBag.speakers = new List<string[]>(); 
     var rdr = cmd.ExecuteReader(); 
     dt.Load(rdr); 

     for (int n = 0; n < dt.Rows.Count; n++) 
     { 
      if (!String.IsNullOrWhiteSpace(Convert.ToString(dt.Rows[n]["UserName"]))) 
      { 
       // speakers returns String[4] array instead of null value 
       var speakers = new String[4] { 
        Convert.ToString(dt.Rows[n]["Id"]), 
        Convert.ToString(dt.Rows[n]["UserName"]), 
        Convert.ToString(dt.Rows[n]["List_Order"]), 
        Convert.ToString(dt.Rows[n]["LoggedIn"]) 
       }; 

       ViewBag.speakers.Add(speakers); 
      } 
     } 

     conn.Close(); 
    } 
} 

NB:DataTable内容を反復するDataTable.Loadと、単純なforループを使用して

は、私はこの1つにグーカン・クルトの答えを修正SqlDataReader.Read()は前進のみで、それは意志戻っfalse最後の後行に達しました。DataReader.Readメソッドがfalseを返した場合にnull参照に割り当てられたViewBag.speakersは、whileループは実行されません。 DataTable.Loadメソッドを使用すると、ExecuteReaderから返されたデータは、SqlDataReaderが閉じられたか最後の行に達した後も保持されます。

第2に、あなたはreader.Read() only read once even when there are multiple rows to readの問題を見るかもしれませんが、IMHOは行の長さが既にわかっているか固定サイズであるとしか動作しないようです。データリーダーが閉じられる前にSqlDataReader.RecordsAffectedを使用することは不可能であるため、行数を取得する別の方法がSqlDataReaderから必要です。

参考文献:

Populate data table from data reader

SqlDataReader.Read()

SqlDataReader.RecordsAffected

DataTable.Load()