简体   繁体   English

MVC5 / C#-无法对空引用执行运行时绑定

[英]MVC5 / C# - Cannot perform runtime binding on a null reference

I'm trying to figure out what's causing a Cannot perform runtime binding on a null reference error from this code: 我正在尝试找出导致此代码中Cannot perform runtime binding on a null reference错误Cannot perform runtime binding on a null reference

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++;
    }
}

The n++ increment seems to be the cause of this error and I don't understand why. n++增量似乎是导致此错误的原因,我不明白为什么。

Updated code to reflect possible solutions. 更新了代码以反映可能的解决方案。 However, the error still remains. 但是,错误仍然存​​在。

Tried this with the same result: 尝试了同样的结果:

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++;
}

Calling the .ToString() method on a null column value can result in the Cannot perform runtime binding on a null reference . 在空列值上调用.ToString()方法可能导致Cannot perform runtime binding on a null reference Use Convert.ToString() instead; 使用Convert.ToString()代替; it will return an empty string if you attempt to convert a null value and won't require additional code for null checking. 如果您尝试转换null值,并且不需要其他代码进行null检查,它将返回一个空字符串。

There are two issues in your code: 您的代码中有两个问题:

Consider this: 考虑一下:

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

This simplified piece of code throws Cannot perform runtime binding on a null reference since speakers is not defined (null reference). 此简化的代码抛出过程由于未定义发言人(空引用)而无法Cannot perform runtime binding on a null reference

You can fix it by defining speakers in the dynamic ViewBag before the loop: 您可以通过在循环之前在动态 ViewBag中定义speakers来解决此问题:

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

The second issue: 第二期:

ViewBag.speakers[n] = speakers;

speakers in your code is a List, you might want to define ViewBag.speakers as a List<List<string>> and call .Add(speakers) instead of accessing using an index (you might get index was out of range ) 代码中的扬声器是一个列表,您可能希望将ViewBag.speakers定义为List<List<string>>并调用.Add(speakers)而不是使用索引进行访问(您可能会获得索引超出范围

ViewBag is a dynamic object and when you try to do assignments to its properties, the null check will happen in runtime. ViewBag是一个动态对象,当您尝试对其属性进行赋值时,将在运行时进行空检查。 You get this error because ViewBag.speakers is either null, or it throws an exception while trying to access its nth slot with indexer (maybe its size is less than n , or it doesn't define an indexer at all). 您收到此错误的原因是ViewBag.speakers为null,或者尝试使用索引器访问第nth插槽时抛出异常(也许其大小小于n ,或者根本没有定义索引器)。 You should initialize ViewBag.speakers before adding elements to it. 您应该先初始化ViewBag.speakers然后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);
    }
}

Your problem seems originated from usage of Read method after ExecuteReader , which gives null reference on dynamic object ViewBag.speakers at certain point that enough to throw runtime binding exception on view side. 您的问题似乎源于ExecuteReader之后对Read方法的使用,该方法在某个点上对动态对象ViewBag.speakers给出了空引用,足以在视图侧引发运行时绑定异常。

Using DataTable.Load and simple for-loop to iterate DataTable contents, I modified Gökhan Kurt 's answer to this one: 使用DataTable.Load和简单的for循环来迭代DataTable内容,我修改了GökhanKurt对此的回答:

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: SqlDataReader.Read() is forward-only, it will returns false after last row has reached. 注意: SqlDataReader.Read()是只读的,到达最后一行后它将返回false The ViewBag.speakers assigned to null reference if the DataReader.Read method returns false, thus while loop is not executed. 如果DataReader.Read方法返回false,则分配给null引用的ViewBag.speakers因此不执行while循环。 Using DataTable.Load method keeps returned data from ExecuteReader even after SqlDataReader is closed or reached last row. 即使在SqlDataReader关闭或到达最后一行之后,使用DataTable.Load方法仍保留ExecuteReader返回的数据。

Secondly, you may look at reader.Read() only read once even when there are multiple rows to read problem, but IMHO it seems only work when the row length is already known or fixed size. 其次,您可能会看到reader.Read()即使有多个要读取的行也只能读取一次 ,但是恕我直言,它似乎仅在已知行长或固定大小时才起作用。 Since it is impossible to use SqlDataReader.RecordsAffected before the data reader is closed, you need another way to get row count from SqlDataReader . 由于在关闭数据读取器之前不可能使用SqlDataReader.RecordsAffected ,因此需要另一种方法来从SqlDataReader获取行数。

References: 参考文献:

Populate data table from data reader 从数据读取器填充数据表

SqlDataReader.Read() SqlDataReader.Read()

SqlDataReader.RecordsAffected SqlDataReader.RecordsAffected

DataTable.Load() DataTable.Load()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法对 mvc 中的 null 引用执行运行时绑定 - Cannot perform runtime binding on a null reference in mvc 无法对空引用 C# Excel 执行运行时绑定 - Cannot perform runtime binding on null reference C# Excel ASP.NET MVC 4 - 无法对空引用执行运行时绑定 - ASP.NET MVC 4 - Cannot perform runtime binding on a null reference MVC代码中的RuntimeBinderException&#39;无法对空引用执行运行时绑定&#39; - RuntimeBinderException 'Cannot perform runtime binding on a null reference' in MVC code MVC-3视图中的异常无法对空引用执行运行时绑定 - Exception in MVC - 3 view cannot perform runtime binding on a null reference C#异常:在检查是否为null时,无法对空引用执行运行时绑定 - C# Exception: Cannot perform runtime binding on a null reference while checking whether it is null or not 使用C#从Outlook 2007发送电子邮件时,无法对空引用执行运行时绑定 - Cannot perform runtime binding to null reference when sending email from Outlook 2007 using C# 无法对 VS2019 中 C# String.IsNullorEmpty 上的 null 引用执行运行时绑定 - Cannot perform runtime binding on a null reference on C# String.IsNullorEmpty in VS2019 无法对空引用错误执行运行时绑定 - Cannot perform runtime binding on a null reference error 无法对空引用异常执行运行时绑定 - Cannot perform runtime binding on a null reference exception
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM