无法将类型 'System.DBNull' 的对象转换为类型 'System.DateTime'
Unable to cast object of type 'System.DBNull' to type 'System.DateTime'
嗨,我正在尝试制作一个通知系统。基本上,当我添加一个新行时,通知将实时显示在我的通知页面上(我将 signalR 与剃须刀页面 asp.net 一起使用)。但出于某种原因,当我进入该页面时,出现以下错误:无法将类型 'System.DBNull' 的对象转换为类型 'System.DateTime'。
在 myWebApp.Controllers.SpeedListener.GetAlarmList() 在 \myWebApp\Controllers\SpeedListener.cs:line 83
在 \myWebApp\Controllers\SpeedListener.cs: 第 43 行
中的 myWebApp.Controllers.SpeedListener.ListenForAlarmNotifications()
显然控制器有问题。
这是控制器的代码
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 中的 table 名称称为 'notification',我有两个名为 'bericht' 的列,类型为 varchar 和 'datumnu',类型为 date。
编辑 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() });
}
嗨,我正在尝试制作一个通知系统。基本上,当我添加一个新行时,通知将实时显示在我的通知页面上(我将 signalR 与剃须刀页面 asp.net 一起使用)。但出于某种原因,当我进入该页面时,出现以下错误:无法将类型 'System.DBNull' 的对象转换为类型 'System.DateTime'。 在 myWebApp.Controllers.SpeedListener.GetAlarmList() 在 \myWebApp\Controllers\SpeedListener.cs:line 83 在 \myWebApp\Controllers\SpeedListener.cs: 第 43 行
中的 myWebApp.Controllers.SpeedListener.ListenForAlarmNotifications()显然控制器有问题。 这是控制器的代码
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 中的 table 名称称为 'notification',我有两个名为 'bericht' 的列,类型为 varchar 和 'datumnu',类型为 date。
编辑 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() });
}