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, 4 meses, 29 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 controlador SpeedListener.

    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étodo IsDBNull() de NpgsqlDataReader 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 tipo DateTime. Esto ocurre cuando la columna datumnu en tu tabla notification contiene valores NULL.

    Para resolver este problema, puedes utilizar el método IsDBNull para comprobar si el valor de datumnu es NULL antes de intentar convertirlo a DateTime. Si es NULL, 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