【问题标题】:Unable to cast object of type 'System.DBNull' to type 'System.DateTime'无法将“System.DBNull”类型的对象转换为“System.DateTime”类型
【发布时间】:2021-03-26 23:01:07
【问题描述】:

您好,我正在尝试制作通知系统。基本上,当我添加新行时,通知将实时显示在我的通知页面上(我将 signalR 与剃须刀页面 asp.net 一起使用)。但由于某种原因,当我进入该页面时,我收到以下错误:无法将类型为“System.DBNull”的对象转换为类型“System.DateTime”。 在 \myWebApp\Controllers\SpeedListener.cs:line 83 中的 myWebApp.Controllers.SpeedListener.GetAlarmList() 在 myWebApp.Controllers.SpeedListener.ListenForAlarmNotifications() 在 \myWebApp\Controllers\SpeedListener.cs:line 43

显然控制器有问题。 这是控制器的代码

namespace myWebApp.Controllers
{
    public class SpeedListener :Controller
    {
        private IHubContext<speedalarmhub> _hubContext;
        private IMemoryCache _cache;
        public SpeedListener(IHubContext<speedalarmhub> hubContext,IMemoryCache cache)
        {
            _hubContext = hubContext;
            _cache = cache; 
        }
        public static string  cs = Database.Database.Connector();
        public void ListenForAlarmNotifications()
        {
            NpgsqlConnection conn = new NpgsqlConnection(cs);
            conn.StateChange += conn_StateChange;
            conn.Open();
            var listenCommand = conn.CreateCommand();
            listenCommand.CommandText = $"listen notifytickets;";
            listenCommand.ExecuteNonQuery();
            conn.Notification += PostgresNotificationReceived;
            _hubContext.Clients.All.SendAsync(this.GetAlarmList());
            while (true)
            {
                conn.Wait();
            }
        }
        private void PostgresNotificationReceived(object sender, NpgsqlNotificationEventArgs e)
        {

            string actionName = e.Payload.ToString();
            string actionType = "";
            if (actionName.Contains("DELETE"))
            {
                actionType = "Delete";
            }
            if (actionName.Contains("UPDATE"))
            {
                actionType = "Update";
            }
            if (actionName.Contains("INSERT"))
            {
                actionType = "Insert";
            }
            _hubContext.Clients.All.SendAsync("ReceiveMessage", this.GetAlarmList());
        }
        public string GetAlarmList()
        {
            List<NotificationModel> not = new List<NotificationModel>();
            using var con = new NpgsqlConnection(cs);
            {
                string query = "Select datumnu, bericht FROM notification";
                using NpgsqlCommand cmd = new NpgsqlCommand(query, con);
                {
                    cmd.Connection = con;
                    con.Open();
                    using (NpgsqlDataReader dr = cmd.ExecuteReader())
                    {
                        
                        while (dr.Read())
                        {
                            not.Add(new NotificationModel { Datenow = ((DateTime) dr["datumnu"]).ToString("yyyy/MM/dd"), Bericht = dr["bericht"].ToString() });
                        }
                    }
                    
                    con.Close();
                }
            }
            _cache.Set("notification", SerializeObjectToJson(not));
            return _cache.Get("notification").ToString();
        }
        public String SerializeObjectToJson(Object notification)
        {
            try
            {
                
                return  Newtonsoft.Json.JsonConvert.SerializeObject(notification);
            }
            catch (Exception) { return null; }
        }
        private void conn_StateChange(object sender, System.Data.StateChangeEventArgs e)
        {

            _hubContext.Clients.All.SendAsync("Current State: " + e.CurrentState.ToString() + " Original State: " + e.OriginalState.ToString(), "connection state changed");
        }
    }
}

如果需要,这里是我的中心

namespace myWebApp.Hubs
{
     
    public class speedalarmhub : Hub
    {
        private IMemoryCache _cache;
        private IHubContext<speedalarmhub> _hubContext;
         public speedalarmhub(IMemoryCache cache, IHubContext<speedalarmhub> hubContext)
        {
            _cache = cache;
            _hubContext = hubContext; 
        }

        public async Task SendMessage()
        {
            if (!_cache.TryGetValue("notification", out string response))
            {
                SpeedListener speedlist = new SpeedListener(_hubContext,_cache);
                speedlist.ListenForAlarmNotifications();
                string jsonspeedalarm = speedlist.GetAlarmList();
                _cache.Set("notification", jsonspeedalarm);
                await Clients.All.SendAsync("ReceiveMessage", _cache.Get("notification").ToString());
            }
            else
            {
                await Clients.All.SendAsync("ReceiveMessage", _cache.Get("notification").ToString());
            }
        }

    }
}

postgresql 中的表名为“通知”,我有两列名为“bericht”,类型为 varchar,“datumnu”,类型为日期。

【问题讨论】:

  • datumnu 的值为空。我建议在您的数据库中创建此字段not null
  • 或者检查dr["datumnu"]是否为空。
  • 哦,好的,谢谢伙计们,它成功了,我不得不删除某些列为空的所有行

标签: c# asp.net postgresql razor signalr


【解决方案1】:

编辑建议mjwills DateTime 不接受空值。检查该值是否为空并分配一个默认值

while (dr.Read())
{
    not.Add(new NotificationModel { Datenow = ((DateTime) dr["datumnu"]).ToString("yyyy/MM/dd"), Bericht = dr["bericht"].ToString() });
}

成为

while (dr.Read())
{
    DateTime defaultDateTime = DateTime.Now;
    if(dr.IsNull("datumnu")){
        defaultDateTime = (DateTime)dr["datumnu"];
    }

    not.Add(new NotificationModel { Datenow = defaultDateTime, Bericht = dr["bericht"].ToString() });
}

单行

while (dr.Read())
{
    not.Add(new NotificationModel { Datenow = (dr.IsNull("datumnu") ? DateTime.Now : (DateTime)dr["datumnu"]), Bericht = dr["bericht"].ToString() });
}

【讨论】:

  • if(dr.IsNull("datumnu")){ 我怀疑你不见了!
猜你喜欢
  • 1970-01-01
  • 2021-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多