Incapaz de lanzar objeto de tipo 'System. DBNull para escribir 'System. Fecha '
Hi im tratando de hacer un sistema de notificación. Básicamente cuando agregue una nueva fila, una notificación se mostrará en mi página de notificaciones en tiempo real (utiliza la señalR con páginas de afeitar asp.net). Pero por alguna razón cuando me pongo en esa página, obtengo estos errores: Incapaz de lanzar objeto de tipo 'System. DBNull para escribir 'System. DateTime'. en myWebApp.Controllers.SpeedListener.GetAlarmList() en \myWebApp\Controllers\SpeedListener.cs:line 83 en myWebApp.Controladores.SpeedListener.Listener.ListenForAlarmNotifications() en \myWebApp\Controllers\SpeedListener.cs:line 43
Así que aparentemente hay un problema en el controlador. Aquí está el código del controlador
namespace myWebApp.Controllers
{
public class SpeedListener :Controller
{
private IHubContext _hubContext;
private IMemoryCache _cache;
public SpeedListener(IHubContext 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 not = new List();
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");
}
}
}
Si es necesario aquí es mi centro
namespace myWebApp.Hubs
{
public class speedalarmhub : Hub
{
private IMemoryCache _cache;
private IHubContext _hubContext;
public speedalarmhub(IMemoryCache cache, IHubContext 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());
}
}
}
}
el nombre de la tabla en postgresql se llama 'notificación', tengo dos columnas llamada 'bericht' con el tipo varchar y 'datumnu' con fecha de tipo.
Pregunta hecha hace 3 años, 5 meses, 7 días - Por codesculptor3f6e
3 Respuestas:
-
Editar sugerida mjwillsDateTime no aceptes valor nulo. Compruebe si el valor es nulo y asignar un valor predeterminado
while (dr.Read()) { not.Add(new NotificationModel { Datenow = ((DateTime) dr["datumnu"]).ToString("yyyy/MM/dd"), Bericht = dr["bericht"].ToString() }); }
Conviértete
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() }); }
en línea individual
while (dr.Read()) { not.Add(new NotificationModel { Datenow = (dr.IsNull("datumnu") ? DateTime.Now : (DateTime)dr["datumnu"]), Bericht = dr["bericht"].ToString() }); }
Respondida el Dec 16, 2020 a las 09:42 - por compilercaptain
Votos positivos: 0 | Votos negativos: 0 -
El error que estás experimentando ocurre porque estás intentando convertir un valor DBNull en un tipo DateTime en el método
GetAlarmList()
de tu controladorSpeedListener
.Para solucionar este problema, necesitas realizar una verificación adicional para verificar si el valor recuperado del campo
datumnu
es en realidad DBNull antes de intentar convertirlo a un tipo DateTime. Puedes utilizar el métodoIsDBNull()
deNpgsqlDataReader
para realizar esta verificación.Aquí te dejo una modificación en la sección relevante de tu código para manejar el DBNull:
csharp while (dr.Read()) { DateTime? dateNu = null; if (!dr.IsDBNull(dr.GetOrdinal("datumnu"))) { dateNu = dr.GetDateTime(dr.GetOrdinal("datumnu")); } string bericht = dr["bericht"].ToString(); not.Add(new NotificationModel { Datenow = dateNu.HasValue ? dateNu.Value.ToString("yyyy/MM/dd") : "", Bericht = bericht }); }
Al hacer esto, verificarás si el campo
datumnu
es DBNull antes de intentar convertirlo a un tipo DateTime. Si es DBNull, asignarás un valor predeterminado al DateTime. Esto debería solucionar el error de DBNull que estás experimentando. ¡Espero que esto te ayude a solucionar el problema en tu código!Respondida el Dec 17, 2020 a las 09:44 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
El error se produce porque estás intentando convertir un valor
DBNull
a un tipoDateTime
. Esto ocurre cuando la columnadatumnu
en tu tablanotification
contiene valoresNULL
.Para resolver este problema, puedes utilizar el método
IsDBNull
para comprobar si el valor dedatumnu
esNULL
antes de intentar convertirlo aDateTime
. Si esNULL
, puedes asignarle un valor predeterminado o ignorarlo.Aquí tienes el código modificado con la comprobación
IsDBNull
:csharp using System; namespace myWebApp.Controllers { public class SpeedListener : Controller { // ... public string GetAlarmList() { List
not = new List (); 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()) { string datumnu = dr["datumnu"].ToString(); string bericht = dr["bericht"].ToString(); // Comprueba si datumnu es NULL if (dr.IsDBNull(dr.GetOrdinal("datumnu"))) { // Asigna un valor predeterminado o ignora el valor datumnu = "1900-01-01"; } not.Add(new NotificationModel { Datenow = datumnu, Bericht = bericht }); } } con.Close(); } } // ... } } } Esto debería resolver el error y permitirte recuperar y mostrar correctamente los datos de la tabla
notification
.Respondida el Dec 17, 2020 a las 09:54 - por Gemini
Votos positivos: 0 | Votos negativos: 0