0

Después de Varios Intentos y Prueba y Error, Logre tomar una imagen, convertirla, subirla a la Base de datos y logre también bajarla y mostrarla, todo eso OK, no hay problema. Pero la situación se presenta a la hora de hacer EDICIÓN del registro, por que si bien logro mostrar la imagen a la hora de querer editar alguno campos de un registro al volver al Controller, el compilador me reclama que el objeto no esta instanciado (if (file.FileName != null)), lo cual no me deja avanzar en la ejecución del código. Aca les presento el código html, donde muestro y también donde hago la captura de la posible nueva imagen:

 <td class="text-center">
  <label>Foto</label>
    <img src="data:image /jpg; base64, @Model.Imagen" style="max-height: 20vh;
       object-fit:contain;" name="Foto" />
 </td>
 <td class="text-center">
   <label>Seleccionar Una Imagen</label>
   <div class="input-group flex-nowrap">
     <span class="input-group-text" id="addon-wrapping">
        <i class="fa-regular fa-image"></i></span>
     <input type="file" name="Foto" accept=".gif, .jpg, .jpeg, .png"
      aria-describedby="addon-wrapping"
      placeholder="Inserte Una Imagen"
      title="Seleccione Una Imagen" />
   </div>
</td> 

y Acá les inserto el código del controller

[HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult EditEmple(Empleado empleado, IFormFile file)
        {
            try
            {
                if (empleado.RutEmpleado != null)
                {
                    if (file.FileName != null)
                    {
                        byte[] bytes;
                        using (Stream fs = file.OpenReadStream())
                        {
                            using (BinaryReader br = new(fs))
                            {
                                bytes = br.ReadBytes((int)fs.Length);
                                empleado.Imagen = Convert.ToBase64String(bytes, 0, bytes.Length);
                            }
                        }
                    }
                    // Fin de Conversion de Imagen
                    _context.ModEmpleado(empleado.IdEmpleado, empleado.RutEmpleado, empleado.Nombre, empleado.ApePat, empleado.ApeMat, empleado.IdDepto,
                         empleado.IdCarg, empleado.Anexo, empleado.EmailEmp, empleado.UserName, empleado.Password, empleado.ConfPassWord, empleado.FechaIncorporacion,
                         empleado.IdEmpresa, empleado.IdTipoRemu, empleado.IdAfp, empleado.IdSalud, empleado.ValAdic, empleado.IdSexo, empleado.IdNac,
                         empleado.IdBanco, empleado.IdTipCta, empleado.NumCta, empleado.CallePje, empleado.NumCasa, empleado.VillPobl, empleado.IdCom,
                         empleado.IdProv, empleado.FonoPart, empleado.Email, empleado.FechaNacimiento, empleado.Imagen, empleado.PersonaEmergencia,
                         empleado.FonoEmergencia, empleado.FechaDespido);
                    TempData["successMessage"] = "Datos Actualizados Correctamente";
                    return RedirectToAction("Index");
                }
                else
                {
                    TempData["errorMessage"] = "Problema de Actualización, Revise!";
                    return RedirectToAction("Index");
                }
            }
            catch (Exception ex)
            {
                TempData["errorMessage"] = ex.Message;
                return RedirectToAction("Index");
            }
        }

Entonces, la Pregunta es Alguien podría indicarme como puedo validar el hecho de que si la imagen viene vaciá, por el hecho que no se hizo ningún cambio, pueda pasar por la pregunta sin problema. Gracias

2 respuestas 2

0

No evalues el file.FileName sino directamente el file

if (file != null)

El valor el FileName es irrelevante puesto que no lo usas nunca. Esto también es válido para la creación de Empleado. El file directamente estará en null si no se seleccionó ningún archivo

3
  • vale, gracias, pero entonces como evalúo si el usuario cambio o no, la foto por una nueva??? Commented el 18 jul. 2023 a las 22:56
  • Si el usuario no ha agregado ningún nuevo archivo entonces no está tratando de editarlo, recibe null desde la UI y no actualizes ese campo en BD Commented el 19 jul. 2023 a las 20:12
  • saludos, Gracias, lo que hice fue preguntar en el SP si el valor de imagen esta null, si es asi, que modificara los otros campos y no el null, else modifique todo, gracias por la ayuda y consejos Commented el 20 jul. 2023 a las 21:58
0

Evidentemente tienes que comprobar si if (file != null), pero más allá de eso, te presento algunos concejos:

1.- Uso del operador ?

Por ejemplo tu tienes

if (empleado.RutEmpleado != null)

Supongamos que empleado puede ser null, entonces tendrías que hacer esto

if (empleado !=null && empleado.RutEmpleado != null)

Imagina tuvieras que comprobar 10 objetos anidados (una locura), para eso usas el ?

if (empleado?.RutEmpleado != null)

2.- Sobre anidación del if

Si tu tienes esta situación

if (empleado.RutEmpleado != null)
{
   //mucho codigo
}
else{
  return algo;
}

Debes invertir la condición del if, lo que te ahorra una indicación, ya que el else no es necesari

if (empleado.RutEmpleado == null)
{
   return algo;
}
//mucho codigo

3.- Múltiples using

Cuando tienes muchos using consecutivos, no es necesario anidarlos todos

Esto

byte[] bytes;
using (Stream fs = file.OpenReadStream())
{
   using (BinaryReader br = new(fs))
   {
      bytes = br.ReadBytes((int)fs.Length);
      empleado.Imagen = Convert.ToBase64String(bytes, 0, bytes.Length);
   }
}

Se puede escribir como:

using (Stream fs = file.OpenReadStream())
using (BinaryReader br = new(fs))
{
    byte[] bytes = br.ReadBytes((int)fs.Length);
    empleado.Imagen = Convert.ToBase64String(bytes, 0, bytes.Length);
}

4.- Pasar como argumento el objeto y no cada una de sus propiedades

Esto que tu tienes:

 _context.ModEmpleado(empleado.IdEmpleado, empleado.RutEmpleado, empleado.Nombre, empleado.ApePat, empleado.ApeMat, empleado.IdDepto,
                         empleado.IdCarg, empleado.Anexo, empleado.EmailEmp, empleado.UserName, empleado.Password, empleado.ConfPassWord, empleado.FechaIncorporacion,
                         empleado.IdEmpresa, empleado.IdTipoRemu, empleado.IdAfp, empleado.IdSalud, empleado.ValAdic, empleado.IdSexo, empleado.IdNac,
                         empleado.IdBanco, empleado.IdTipCta, empleado.NumCta, empleado.CallePje, empleado.NumCasa, empleado.VillPobl, empleado.IdCom,
                         empleado.IdProv, empleado.FonoPart, empleado.Email, empleado.FechaNacimiento, empleado.Imagen, empleado.PersonaEmergencia,
                         empleado.FonoEmergencia, empleado.FechaDespido);

Es una locura total, pasa el ebjeto entero. Para eso obviamente debes editar tu función ModEmpleado

 _context.ModEmpleado(empleado);

5.- Evaluar si ha editado la imagen

En uno de tus comentarios, dices que quieres comprobar si se ha cambiado la imagen o no. No te sirve comprobar el nombre, 2 imágenes diferentes pueden perfectamente tener el mismo nombre. En la práctica no existe un forma "fácil" de comprobar esta situación.

Lo que conviene hacer en este caso, es siempre pisar la imagen. Es decir cada vez que file sea distinto a null, tu la guardas como si se estuviera editando, aunque sea la misma.


Código con las mejoras

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult EditEmple(Empleado empleado, IFormFile file)
{
    if(empleado?.RutEmpleado == null)
    {
        TempData["errorMessage"] = "Problema de Actualización, Revise!";
        return RedirectToAction("Index");
    }

    if (file?.FileName != null)
    {
        using (Stream fs = file.OpenReadStream())
        using (BinaryReader br = new(fs))
        {
            byte[] bytes = br.ReadBytes((int)fs.Length);
            empleado.Imagen = Convert.ToBase64String(bytes, 0, bytes.Length);
        }
    }

    try
    {
        _context.ModEmpleado(empleado);
        TempData["successMessage"] = "Datos Actualizados Correctamente";
        return RedirectToAction("Index");
    }
    catch (Exception ex)
    {
        TempData["errorMessage"] = ex.Message;
        return RedirectToAction("Index");
    }
}

2
  • Gracias por tus comentarios y consejos, lo he seguido, pero al usar _context.ModEmpleado(empleado); y en el context modifique de la siguiente manera; public void ModEmpleado(Empleado empleado) { Database.ExecuteSql($"SP_UPD_EMPL {empleado}"); } , pero al probar me envia en umesaje de error : - $exception {"The current provider doesn't have a store type mapping for properties of type 'Empleado'."} System.InvalidOperationException Gracias Commented el 19 jul. 2023 a las 22:29
  • Gracias por los comentarios y sugerencia, los he seguido. he modificado a: _context.ModEmpleado(empleado); y en el context lo deje de la siguiente manera: public void ModEmpleado(Empleado empleado) { Database.ExecuteSql($"SP_UPD_EMPL {empleado}"); }; pero me envia el sguiente mensaje: {"The current provider doesn't have a store type mapping for properties of type 'Empleado'."} Commented el 19 jul. 2023 a las 22:34

¿No es la respuesta que buscas? Examina otras preguntas con la etiqueta o formula tu propia pregunta.