Transcripciones
1. Introducción: Hey chicos, bienvenidos a mi nuevo curso, ASP.Net core, arquitectura sólida y limpia. Soy tu instructor, Travolta Williams. Tengo más de 10 años de experiencia como ingeniero de software y conferencista. En este curso, vamos a estar viendo bastantes cosas. Vamos a ver implementar principios sólidos y arquitectura
limpia en una aplicación ASP.Net Core. En el camino, vamos a trabajar con herramientas avanzadas como mediador o bottom-up o Fluent API para la validación, estaremos construyendo Global Exception Handling y logging. Estaré mirando el patrón C QRS, que es un patrón maravilloso que mantiene nuestro código segregado y en tamaño de bit es para máxima integración y extensibilidad. Al finalizar este curso, vamos a entender cómo hacer pruebas unitarias, cómo integrar servicios de terceros en una aplicación y ver cómo podemos implementarlo con fines de producción. Si bien, los requisitos para este curso incluyen Visual Studio 2019 y dotnet five, o la última versión. En el momento en que estás haciendo este curso, todo lo que vamos a estar haciendo es a prueba de futuro y estos principios se
pueden transferir a las últimas versiones sin ningún problema. Para sacar el máximo provecho de este curso, sí te recomiendo que tengas cierta cantidad de conocimientos de programación C Sharp y dotnet así como conocimiento de desarrollo de bases de datos. De cualquier manera, haré que el contenido sea muy amigable para principiantes y no debes tener absolutamente ningún problema en
seguir y saber que tienes toda la información que necesitas. Te veré pronto en el curso.
2. Comprender la arquitectura limpia: Muy bien, así que hemos mirado los principios que rigen la arquitectura limpia de las aplicaciones. Ahora veamos a qué nos referimos exactamente por arquitectura limpia. Porque la arquitectura limpia no significa necesariamente un buen software. Bueno es muy relativo a quien lo está viendo. Por ejemplo, si se le encomendó desarrollar un sistema de gestión de leads para el departamento de RRHH y lo hiciste, y RHH está contento, entonces es un buen software. No obstante, si no lo hiciste siguiendo estos principios, entonces podría verse como software malo, pero las prácticas brotan el desarrollo de software en general, por tu equipo o quien sea tu sucesor cuando están tratando de mantener esta aplicación. Por lo que la arquitectura limpia no es necesariamente directamente proporcional al buen software. Depende de quién sea el receptor fuera y en qué momento. Entonces vamos a discutir todo lo que entra en desarrollo de
software y los diferentes tipos de arquitectura para que
podamos apreciar plenamente cuándo necesitaríamos intensificar un poco más
nuestras consideraciones de diseño y cuáles son los pros y los contras de esto son. Por lo que la primera que vamos a querer mirar sería todo en una sola arquitectura. Y lo haré todo en una sola arquitectura, es más fácil de entregar. Puede ser estable y verse como una solución a largo plazo. Todo en uno arquitectura podría ser fácilmente cuando nos scufled a estrenar es ser dotnet aplicación Core. O si esta es la primera vez que haces ASP.Net Core, probablemente
estés más familiarizado con Ruby on Rails o larva o jungla. Una vez que tengas ese diseño general del proyecto, eso podría verse fácilmente como una arquitectura todo en uno. Tienes todas las carpetas y todo lo que tienes que hacer es crear tus archivos, crear tu completo hace esa separación de preocupaciones ahí mismo y todo está bien, el software funcionará. No obstante, definitivamente es difícil hacer cumplir principios sólidos. Cuanto más tengas que empacar en esto todo en una arquitectura es más olores de código y malas prácticas que podrían tener que verse comprometidas. Está bien, así a medida que crece, se vuelve más difícil de mantener y su testabilidad. Y cuando nos sentamos esta estabilidad, nos referimos como con la depuración y por pruebas unitarias de extensión, la capacidad de probar dos unidades de esto todo en una sola arquitectura. Esa capacidad disminuye a medida que los roles de aplicación. A continuación, queremos ver la arquitectura en capas. Y toda arquitectura estratificada es un paso por encima de todo en uno donde en lugar de separar nuestros módulos o nuestros trozos de código y archivos, lo siento, por carpetas, empezamos a buscar crear proyectos y hacer referencia a estos proyectos. Por lo que en ESP dotnet Core y en sus obligaciones en general, puedes desarrollar bibliotecas
de clases donde pongas todas tus clases y solo haces referencia a ellas como necesites. Y luego terminarías con diferentes capas. Tienes una capa que se ocupa de las cosas de la interfaz de usuario. Tienes una capa que necesita con la lógica empresarial. Y tienes una capa que grava la inflamación entre base de datos y la lógica empresarial hasta. Y luego terminas con una estratificada nuestra aplicación. Ahora, es más fácil, definitivamente imponer principios
sólidos y es más fácil minton bases de código más grandes. No obstante, esto todavía accede a una aplicación debido a que todas estas capas siguen siendo algo dependientes entre sí. Por lo que todavía no estamos aprovechando plenamente todo el principio de inversión de dependencia, así
como todo el principio de acoplamiento suelto. Y ahora por fin, estamos viendo The only on architecture que se enseña en gran medida como arquitectura limpia. Ahora cuando hablamos solo de arquitectura, estamos hablando de diferentes formas de ver capas. Y en esta etapa, queremos apoyar cualquier tipo de aplicación. Quieres tener todo muy modular para que podamos poner en un nuevo módulo sin interrumpir el resto de la base de código. Podemos tomar auto módulo y podemos hacer cambios y probar más fácilmente sin interrumpir las partes existentes de la aplicación. Entonces cuando hablamos de la arquitectura Odeon, estamos hablando de tal vez tener alguna aplicación cliente para la interfaz de usuario. Esta podría ser una aplicación Web ASP.Net. Esta podría ser una aplicación móvil. Estamos hablando de que ambos tengan servicios API que se
sentarán encima de la obligación en el núcleo. Y estos servicios API, una vez más, serían de código abierto. Realmente no le importa lo que sea el cliente y los riesgos es lo que estaremos usando. Pero no le importa si es un cliente móvil, no le importa si es un cliente web, un cliente blazer, y enojar a un cliente, Es solo taxiar datos de la base de datos a quien esté escuchando. Y Buck, No, las pruebas se vuelven mucho más fáciles de hacer porque podemos probar las diferentes capas de forma independiente y luego
podemos probar cómo interactúan las capas entre sí. Entonces si se introduce algo para romper alguna de estas interacciones existentes, entonces podemos detectarla con mayor facilidad. Y desde temprano nulo para la infraestructura estamos hablando del módulo. Entonces estamos hablando de registrar el acceso a datos. Si tenemos más de una base de datos con la que tenemos que estar tratando, deberíamos poder poner en una capa completamente nueva para hablar para deshacer base de datos sin interrumpir nada que la arquitectura existente estaba haciendo con la antigua base de datos. Podemos poner en registro, podemos poner en mapeo, validaciones. Todo puede entrar y nuestra cómoda sin interrumpir nuestra aplicación. Entonces contras, sin embargo, hay una curva de aprendizaje porque se necesita saber qué fue raro y hay diferentes interpretaciones de este tipo de arquitectura. Por lo que puede que veas diferentes sabores. Si lees dos o tres fuentes diferentes, vas a ver dos o tres implementaciones diferentes de su enemigo. Me pregunto cuál es el que debería usar? Por supuesto, el contexto determina mucho de lo que tú y otros desarrolladores hacen, las decisiones que tomas en tu arquitectura. Y así, ya sabes, solo
tienes que usar eso, solo obtén el conocimiento y usa
tu contexto como tu guía y otra estafa a este tipo de arquitecturas que puede ser muy tiempo porque hay mucha su lote más archivos que estarán involucrados cuando podríamos hacer algo con dos archivos ahora probablemente requerirá cinco. No obstante, una vez más, los beneficios serían que tengamos alfombras
sueltas y más testabilidad. Entonces con todo eso dicho, ten cuidado. No todas las aplicaciones necesitan, comillas, arquitectura limpia. buen software satisface las necesidades del negocio y el
software mantenible aumenta la vida útil del software. Por lo que hay que encontrar un equilibrio en todo momento. No veas que cada proyecto que tienes que hacer va a necesitar una arquitectura limpia, empieza pequeño y se extiende según sea necesario.
3. Qué vamos a construir: Bienvenido de nuevo. En este video, estaremos echando un vistazo a la aplicación que queremos construir o reconstruir. Por lo que en mi pantalla tengo un sistema de gestión de leads que se construyó con una velocidad en él core 3.1. Y se ven todas las cosas que se implementaron dentro de esta solución. Ahora, se ve bien y hace lo que fue diseñado para hacer. Entregó capacidades de gestión de licencias al departamento de RRHH. Puedes encontrar el código fuente para esta aplicación en mi cuenta de GitHub y puedes buscar el repositorio leave dash management, dash dotnet core. De hecho, esta es la aplicación que se construyó en mi curso, completa ASP.Net Core y Entity Framework Development. ¿ Por qué fue perfecto para principiantes? Es cierto con muchos olores de código y formas ineficientes de escribir el código que un principiante puede retomar. Pero luego a medida que te pongas más intermedio a avanzado, empezarás a darte cuenta de que son mejores maneras de hacer estas cosas. Y eso es exactamente lo que estaremos discutiendo en este curso. Ahora, sólo tomaré y miraré la estructura del proyecto. Y una vez más, es completamente opcional descargarlo. Simplemente puedes seguir adelante, pero te estaré mostrando algunos de los puntos débiles de la arquitectura y algunas de las decisiones que se tomaron durante el desarrollo de esta aplicación. Uno, verás que esto sólo tiene un proyecto. Ahora si recuerdas antes cuando miramos los diferentes tipos de arquitecturas de proyectos, esto caería justo en eso todo en una sola arquitectura dondequiera que la cosa esté solo en un proyecto, de fácil acceso. Entonces una vez más, para principiante, eso está bien porque quieres vistas, llegas a las vistas que quieres que vaya a datos. Es toda su separación de preocupaciones en este punto está limitada y restringida a solo carpetas. No obstante, en el panorama más amplio, y cuando se quiere agregar más cosas, este proyecto puede engordarse muy a medida que se intenta extenderlo, por lo que será bueno sacarlo. Otra cosa que huele nuestro código que quisiéramos abordar es la repetición de código. Por lo que incluso en la construcción de nuestros modelos de datos, verías que tipo de repetimos algunas de las propiedades. Tenemos ID ahí, tenemos ID aquí otra vez, esas pequeñas cosas en algunos de los controladores, repetimos código cuando no necesariamente lo necesitamos. Y luego mientras estamos en el tema de los controladores, hay lo que llamaremos controladores de grasa aquí. Entonces estamos haciendo mucha lógica empresarial, mucho procesamiento aquí mismo en el controlador, que lo hace muy pesado. Por lo que quieres un poco obstruir esos
procesos de lógica empresarial lejos de tus controladores. Ahora, fuera de las razones de desarrollo para rediseñar y rediseñar esta aplicación desde una perspectiva empresarial o empresarial,
una, RHH quiere extender esta aplicación de la forma en que se construye, ¿verdad? No, es bastante difícil hacer eso sin alterar el código existente. Eso es 1, 2, no es muy comprobable en su estado actual. Entonces aunque intentemos extenderlo, vamos a tener más own off testing porque tenemos que
hacer más pruebas de regresión y pruebas manuales sobre eso. Y luego tres, cuando lo hacemos en una onda de arquitectura limpia, realidad
tenemos la opción de extenderla a diferentes tipos de aplicaciones
cliente y potencialmente implementadas como software como servicio donde la API está llevando a cabo todo el lógica empresarial e interacción con la base de datos y la aplicación cliente es completamente anónima que teníamos. Esta aplicación cliente podría haber sido una aplicación MVC, podría
haber sido una aplicación blazer, podría haber sido una aplicación móvil. Por lo que esa es una de las razones de la propuesta de valor por las que se puede implementar clave y arquitectura. Entonces volviendo a lo que dijimos antes, buen software es el software que hace su trabajo, ¿verdad? No, este es un buen software. El departamento de RHH está tranquilo, contento con él y cómo lo hace, qué tiene que hacer. No obstante, cuando empiezan a pedir más cosas, nos damos cuenta en nuestro dicho técnico que se vuelve un poco más difícil
extenderlo, modificarlo, probarlo. Entonces donde lo estamos protegiendo para que aún podamos entregar toda la funcionalidad que el departamento de RRHH quiere al mismo tiempo que conservamos la capacidad de mantenerla de una manera muy eficiente. En nuestra siguiente lección, comenzaremos a configurar la solución para nuestra nueva arquitectura.
4. Configuración de la solución: Bienvenido de nuevo. En nuestra primera lección práctica, vamos a estar configurando nuestra solución. Por lo que tengo Visual Studio 2019 abierto. Si no tienes Visual Studio 2019 ya instalado, puedes ir fácilmente a Visual Studio dot Microsoft.com slash VS y descargar la edición de la comunidad. El Community Edition es gratuito para uso educativo e individual. Por supuesto, si lo eres, si eres un comercial de lo que se espera conseguir la versión profesional o la de empresa. Una vez que lo hayas descargado, se
te presentará un instalador. Y lo que realmente necesitas de este instalador, al menos es la carga de trabajo de ASP.Net y desarrollo web. Por lo que al marcarlo, estás indicando que quieres ese trabajo a través de él. Verás todas las cargas de trabajo disponibles. Puedes llevarlos si así lo deseas. Por supuesto, cuanto más tomes es más necesitas descargar. Pero para este curso realmente solo necesitas este que te dará todas
las herramientas necesarias para cualquier aplicación Web ASP.Net así como dotnet cinco. Entonces una vez que hayas completado esa configuración o si ya tenías instalada y continúa conmigo. Y vamos a ir a crear un nuevo proyecto. Entonces lo que vamos a hacer es crear una solución en blanco. Tengo en mis plantillas de proyecto recientes. Pero si lo haces por encima de eso, siempre
puedes buscar solución en blanco en esta área y luego obtendrás una solución vacía que no contenga proyectos. Entonces eso es lo que queremos y vamos a estar llamando este proyecto H son puntos dejar gestión. Ahora no hay razón en particular para que yo lo llame así. Se trata de una aplicación de gestión de leads que se está construyendo para el departamento de RRHH. Si se estaba construyendo para una empresa, entonces probablemente querrías decir empresa punto el tipo de sistema. Entonces si quieres, puedes seguir adelante y usar mi nombre o cambiar ese nombre en consecuencia. Pero una vez que hayas puesto un nombre que sea válido, entonces puedes seguir adelante y hacer clic en Crear. Ahora no estaremos escribiendo ningún código en esta lección, pero estaremos sacando esa estructura del proyecto como la necesitamos durante la duración de este curso o de todo este proyecto. Entonces lo primero que voy a hacer es agregar una carpeta y voy a llamar a ésta SRC, abreviatura de fuente, y otra carpeta a la que vamos a llamar pruebas. Ahora bajo SRC, voy a agregar algunas carpetas más. Voy a llamar a ésta la API, porque eso es lo que interactuará con nuestra aplicación cliente. Voy a tener otro llamado core,
uno más llamado infra structure,
y finalmente, uno para la UI. Entonces eso es todo lo que estamos haciendo para esta lección. Simplemente estamos configurando la estructura del proyecto. Entonces, cuando regresemos, comenzaremos a crear los diferentes proyectos que irán en cada una de estas secciones.
5. Crear el proyecto de dominio: Muy bien chicos, bienvenidos de nuevo. En esta lección, estaremos creando nuestros proyectos de dominio. Por lo que nuestros proyectos de dominio irán por debajo de nuestra carpeta central dentro de nuestra aplicación, podemos seguir adelante y agregar un nuevo proyecto. Y lo que vamos a estar haciendo es agregarlo como biblioteca de clases, biblioteca C-sharp Docx de tipo dotnet estándar. Está bien, así que no está en estribor permite
compartir código a través de muchas plataformas diferentes. Por lo que sólo usaremos esa para todas nuestras bibliotecas de clase. Y lo estamos llamando HR dot leave management domain ya que se utilizará para almacenar todos
nuestros objetos de dominio o clases de entidad que se traduzcan a nuestras tablas de base de datos. Para que pueda seguir adelante y golpear Next. Y el marco objetivo aquí es el estándar 2.1 de dotnet. Adelante y golpea Crear. Ahora una vez hecho eso, obtenemos nuestra clase predeterminada uno, que en realidad podemos eliminar y luego empezar a poblar con nuestras clases. Entonces, volviendo a nuestro proyecto en GitHub, simplemente rápidamente, verías que las clases de dominio se llevaban dentro del proyecto en una carpeta llamada data. Por lo que nuestras clases de dominio incluyeron asignación de
licencias, solicitudes de licencia, y tipo de licencia. Si quieres, puedes seguir adelante y recuperarlos, pero voy a estar pasando por ellos de todos modos. Entonces si solo echaras un vistazo rápido a estas clases, verías que cada una tenía una identificación, y también teníamos un montón de propiedades en cada una. Entonces cuando propiedades ese tipo de repetido incluiría fecha creada entre el tipo de hoja y el registro de asignación de hojas. Y entonces es inconsistente porque la gestión de la licencia o lo siento, las solicitudes de
licencia realmente no tienen eso. Entonces estaremos arreglando algunas de esas inconsistencias, además de reducir las repeticiones entre ellas. Entonces voy a empezar con tipos de hojas. Por lo que sólo voy a ir al proyecto click Agregar nueva clase. Lo estamos llamando tipo hoja. Y voy a hacer este foro público No, dentro de tipo hoja, lo que vamos a tener nuestros campos para ID, nombre, Días predeterminados, y cada uno creó. Ahora sí especificé ese campo de fecha, como fecha creada es realmente un campo de auditoría y esto necesita ser teléfono a través de las diferentes clases. Entonces solo voy a seguir adelante y agregar todas las clases de entidad para que puedas pausar, replicar eso. Para la solicitud de licencia, vamos a tener un campo ID, inicio y fechas de fin, tipo de hoja. El dato solicitado, solicita, comentarios, fecha, axón, y aprobado en forma de booleano nullable, y cancelado en forma de booleano. Para que puedas seguir adelante y replicar eso. No, si estás comparando esto con lo que está en la referencia de GitHub, faltan algunos campos, para los
cuales no estamos del todo listos todavía en forma del empleado, que serían algunos datos relacionados con el usuario. Todavía no tenemos eso, así que no estamos priorizando que podamos introducir eso más adelante a través de algunas migraciones. Conoce la tercera entidad que vamos a sumar es asignación de licencias. Y para éste vamos a tener el DNI,
el número de días, la fecha creada, tipo de licencia, ID tipo
hoja, y punto. Una vez más, como que he omitido los campos relacionados con los empleados también. Esas anotaciones de datos. Ahora en cuanto a repetir campos versus la necesidad de tener consistencia con al menos la visa hay que repetir, a
saber, la fecha creada. Por lo general cuando hablamos de auditoría, queremos tener fecha creada,
quién la creó, la fecha modificada,
y quién la modificó por última vez, ¿verdad? Para que así podamos hacer un seguimiento de todo lo que sucede a través de él como casi todos follaron. En realidad resolveríamos algunas de las cosas con todo
el referenciar al empleado y así sucesivamente con estos sentir auditoria. Entonces lo que voy a hacer es introducir otra carpeta en este proyecto de dominio. Y voy a llamar a esta carpeta común. Y luego dentro de común, tendré una clase a la que voy a llamar a esta entidad de dominio. Nadie sabe que mi entidad de dominio base tiene, bueno, es bueno tener todos los campos base que
conozco cada clase o cada entidad de dominio va a necesitar. Voy a hacer de esto una clase abstracta para que no pueda ser instanciada por sí sola. No obstante, puede ser heredado por todos los demás. Entonces esto va a ser ID porque cada mesa va a necesitar una identificación. También voy a tener para otros campos, uno para la fecha creada,
luego creado para entonces una fecha y hora para los datos Last-Modificado y otro para el último modificado por. Ahora con esta entidad de dominio base, puedo saber que todos los demás hereda. Simplemente puedo volver a mi clase de entidad real y dejarla heredar de la entidad de dominio base, incluyendo cualquier referencia que falte usando punto de control. Y ahí se ve que estos campos que tengo INSEAD dejan asignación que tienen los mismos nombres que los de basados en una entidad se están iluminando. Entonces eso significa que no necesito repetirlas. Está bien. Eso se ve un poco más limpio. Está bien, Así que voy y dejo solicitudes de lo que hago lo mismo. Adelante y heredar incluir las referencias faltantes y luego de
repente no necesito ver identificación por aquí tampoco. Y luego en tipo de hoja, hago justo lo mismo, incluyendo referencias faltantes. Y luego puedo quitar todos los campos repetidos. Por lo que se basan en una entidad nos da acceso a ciertos campos que se espera que se repitan en toda entidad ya que todos queremos que tengan estos. Está bien. Entonces con todos esos cambios realizados, sigamos adelante y golpeemos Control Shift y B para hacer una compilación y tenemos una compilación exitosa. Para que podamos pasar a la siguiente tarea.
6. Crear el proyecto de aplicación: Oigan chicos, bienvenidos de nuevo. En esta lección estaremos discutiendo nuestra capa de núcleo de aplicación. Ahora el propósito de esta capa es sentarse entre nuestra aplicación,
siendo la aplicación lo que sería querer acceder a la base de datos y a la base de datos. Por lo que en esta capa se estarán definiendo todos esos parámetros de acceso para mediar entre la aplicación que llama y la propia base de datos. Por lo que este proyecto se sentará directamente dentro de nuestra carpeta central. Entonces sigamos adelante y agreguemos una nueva biblioteca de clases. Y yo quería estar llamando a este uno puntos de HR, dejar aplicación de punto de gestión. Adelante y agrégalo una vez más, estamos usando dotnet poco menos de 2.1 y seguir adelante y crear. Entonces ahora que tenemos nuestra biblioteca de clases, voy a quitar la clase predeterminada, y luego voy a agregar dos carpetas nuevas a este proyecto. Entonces el primero va a ser persistencia y luego encipher sistemas, vamos a tener otra carpeta llamada contratos. Por lo que dentro de los contratos vamos a estar definiendo todas
las obstrucciones para nuestros repositorios. Ahora el jurado está fuera sobre cuáles son las mejores formas de implementar esto. Una vez más, hay unas cuantas opiniones es la arquitectura propuesta, y hay unas cuantas opiniones y algunas opiniones se implementan en base al contexto. Pero sólo voy a explicar por qué estamos usando el patrón de repositorio. Entonces uno, en el, acuerdo con los principios secos, no
queremos repetir consultas con demasiada frecuencia. Además, podría tener operaciones especializadas que
necesite llevar a cabo en cualquiera de estos objetos de dominio. Entonces cuando definas un repositorio por objeto de dominio, entonces puedes tener cotización personalizada o métodos
personalizados dentro de ese repositorio para estos, ¿verdad? No, no estamos implementando el repositorio sin embargo, solo
estamos definiendo el contrato. Entonces el contrato aquí, el primero será una interfaz y lo voy a llamar ij repositorio genérico. Dije clase aquí, haciendo una clase. Pero aunque tengas precaución de que solo puedas convertirla en una interfaz pública. Ahora vamos a decirle a esta interfaz que se implementará relación a una clase llamada T. Así que solo estamos usando genéricos en concordancia con el nombre repositorio genérico para que cualquiera de nuestros objetos de dominio pueda ser utilizado para acceder a la funcionalidad relacionada con la base de datos mediante esta interfaz. Por lo que algunos de los métodos que vamos a implementar en esta interfaz incluyen un GetMethod, por lo que tenemos la tarea T. Y entonces solo puedes seguir adelante e incluir cualquier biblioteca que falte. También vamos a tener tarea, conseguir todo lo que este está regresando. Solo leo listas, sabe si es la primera vez que ves este tipo de datos. Por lo general, y personalmente suelo usar una lista o un nihilista o uno de esos tipos de datos de Colección más populares que leo en una lista. Ese es beneficio es que lo mantiene en un estado de solo lectura por lo que no se puede modificar una vez que se ha extraído de los mesones de datos enviados. Por lo que menos camiones y menos operaciones relacionadas con la base de datos después del pool de datos. Entonces lo veremos en unos pocos, pero ese es el tipo de datos que estoy usando. Una vez más, podrías haber usado fácilmente cualquier otro tipo de colección de tipo T. Pudo haber sido una lista, podría haber sido una colección. Pero entonces leí en la lista está sirviendo el propósito que quería. Vamos a tener la tarea de agregar en donde también Linda tiene tareas que actualizar y eliminar. Entonces se ve que los repositorios genéricos no sólo genéricos para t, sino que también es un genérico en cuanto a la funcionalidad proporciona cuáles son las funciones crud básicas y estándar. También hay una convención de nomenclatura donde la gente pondría la palabra async porque se puede ver donde todos usando tareas aquí. Por lo que algunas veces verías luego definirla como un fregadero. Entonces es obvio que esta va a ser una función asíncrona. Por lo que no podías seguir esa convención de nombres si quieres. No voy a hacerlo, así que podemos seguir adelante. Ahora lo que pasa con el repositorio genérico es que una vez más, son solo las funciones crud genéricas que cada tabla de base de datos puede necesitar realizar alguna vez. No obstante, cuando tienes algo específico para dejar operación de
asignación o una operación de solicitud de licencia, no
puedes construir la sal y el código podría ponerse missy si intentas construirlo en ciertas partes de la aplicación. Entonces lo que vamos a hacer es en comentarios repositorios
específicos basados en nuestro repositorio genérico o ampliar nuestra funcionalidad genérica, pero específica para cualquiera de nuestros objetos de dominio. Entonces solo voy a volver a los contratos y voy a añadir un nuevo ítem en forma de clase una vez más, pero realmente va a ser una interfaz y lo voy a llamar, dejo repositorio de solicitud. Una vez que eso se crea, lo convertimos en una interfaz pública. Y luego le hago saber que se está extendiendo repositorio genérico y es específico de nuestro tipo de clase de solicitud de licencia. De acuerdo, así que dejar solicitud es nuestro dominio. Recuerda que esto era relativo al tipo t Entonces esta es la T que estamos pasando, pero entonces verás aquí que no sabe nada de decir 70. Por lo que necesitamos agregar referencia al dominio de gestión de recursos humanos. Entonces puedes ver que con toda honestidad, eso no me ha funcionado del todo cuando uso su lado, solo pasa a dependencias. Déjame hacer eso otra vez, lo siento, dependencias en proyecto o de un amigo. Y luego solo tomo la referencia a los objetos de dominio. Haga clic en Aceptar. Y entonces puedo saber, incluir que usando declaración aquí. Muy bien, entonces dentro de este repositorio, entonces si tenemos funciones especializadas relativas a solo dejar solicitudes, entonces podemos definirlas aquí con el modelado
del repositorio genérico y sin los otros repositorios específicos necesitando verlo, queremos mantener todo tipo de contenido en un solo lugar. lo que siguiendo este ejemplo, sólo
voy a seguir adelante y defender a los demás repositorios. Dejo asignación y dejaré repositorios de tipo. Por lo que una vez que se realiza esa actividad, terminamos con otras dos interfaces. Por lo que tenemos nuestro repositorio genérico. Tenemos o dejo repositorio de asignación, que está implementando o heredando u otro repositorio yo genérico relativo a dejar asignación. Y luego tenemos eso de nuevo para tipo de hoja con dejo tipo repositorio extendiendo genérico relativo a tipo de dejar. Entonces eso es realmente todo para esta lección donde están sentando los contratos. Y esos contratos están en los foros de estas interfaces. Porque recuerda que no queremos
interrumpir directamente con el código cuando estamos llamando a lo que vamos a estar tratando con abstracciones de esa manera podemos hacer cambios de código sin interrumpir demasiado la cotización del cliente- aplicación lateral.
7. Implementar la Automapper: Oigan chicos, bienvenidos de nuevo. En esta lección vamos a estar sentados auto mapeador. Sepa si no sabe qué es la parte superior de otoño, eso no es problema. En realidad es solo una biblioteca que nos ayuda a convertir entre un tipo de datos a otro. Más simple, ¿verdad? Entonces el contexto detrás de por qué será útil es que estaremos implementando el patrón mediador en un siguiente video. Pero eso mediates o patrón estará actuando como un mecanismo de mensajería entre lo que viene de la planta y lo que necesita ir a la base de datos. Es, en términos generales, mala práctica interactuar directamente con los objetos de dominio, al
menos antes de llegar al repositorio. Eso significa que no deberíamos estar permitiendo que ninguna aplicación de llamada y el cliente, cualquier aplicación que esté hablando con nuestra aplicación en núcleo
nos esté enviando directamente o directamente objetos fuera del tipo de objeto de dominio. En cambio, creamos obstrucción. Por lo que creamos objetos de transferencia de datos o modelos de visualización. Puedes llamarlos cualquiera de ellos, pero en realidad son solo cruces ese tipo de aspecto del objeto de dominio, pero tienen restricciones basadas en la operación. Por lo que editar operación tiene diferentes requisitos de tal vez una operación de creación. Y así presentarías el id 1 y el id no se presentaría en el otro. Una vez más, todo lo que tienes son obstrucciones para eso. Se puede obtener granular o se puede mantener general. Eso depende de ti. El punto es alter mapper ayudará con la conversión entre la obstruida o amigable con el cliente
de este objeto y la versión amigable con la base de datos de este objeto. Esto va a promover el acoplamiento suelto a lo largo de nuestra aplicación. Entonces con todo eso dicho, la configuración no va a ser muy complicada para ésta, lo que voy a hacer dentro de este proyecto de aplicación es crear una nueva carpeta y sólo vamos a llamarla perfiles aunque. El perfil es básicamente solo un archivo de configuración para túnel automotriz que se permite convertir entre un tipo de datos a otro. Entonces voy a crear un vestido nuevo dentro de esta carpeta. Y lo voy a llamar perfil de mapeo. Y luego necesito presentarme y voy a hacer esto público por supuesto, pero necesito ir a NuGet y conseguir nuestro altar Biblioteca Mapper. Entonces solo voy a hacer clic con el botón derecho en dinero. ¿ Se puede conseguir biblioteca? Y luego voy a buscar autor definitivo. Y la que me interesa es la última de las extensiones Bardot para inyección de dependencia. Vendremos con todas las dependencias incluyendo
la biblioteca de PR definitiva base y cualquier otra cosa necesaria para que pueda usarse para inyección de dependencia en consecuencia. Entonces solo voy a seguir adelante e instalar esa. Por supuesto, aceptar y permitir cualquier problema que surja una vez que esté instalado. En lugar de mapear perfil, voy a dejar que herede de una clase llamada perfil. Y esta clase es llamada en auto Mapper Library. De acuerdo, entonces tenemos la configuración del perfil. Eso es bueno. Bueno lo siguiente que voy a definir serían mis objetos de transferencia de datos. Por lo que he creado una nueva carpeta dentro de este proyecto de aplicación. Y en esta carpeta tengo algunos archivos. Uno, tengo un archivo o carpeta común otro con un archivo común llamado detalle base. Tan similar al acarreo y estamos sentados a bordo de objetos de dominio, tenemos un común y luego donde la entidad de dominio base, que tenía algunas propiedades base que deberían estar a través de todos estos objetos de dominio. Es de la misma manera que acabo de hacer detalle basado. Y la propiedad común sería ID. No necesito la fecha creada y demás con los DTL, eso es solo para auditar, así que eso está en segundo plano. Entonces lo que realmente necesito compartir entre todos ellos sería la identificación. Y luego dentro de cada uno de estos, que aún no he hecho esos, entonces tendré otras propiedades que sé que cada uno de ellos necesita
tener para poder taxi con éxito información útil para mí. Por lo que esta parte es tan fácil como ir a dejar tipo y tomar las propiedades que
conoces, querrías permitir que tu aplicación o tus usuarios puedan interrumpirla. Por lo que eso dejaría peticiones. Estas son todas propiedades requeridas. Yo solo estoy literalmente, como ves, solo
estoy copiando y pegando la parte dura realmente fue solo definir el detalle base y dejar que
la herencia se pusiera en esas identificaciones y no detalles, hablar con detalles. Entonces ven aquí que el tipo de hoja se está reteniendo. Se ve que el tipo de hoja se está reteniendo. No dejas que el DTO sepa sobre el dominio. Muy bien, así que esto debería ser de tipo hoja DTO, y esto también debería creer que DTO, y como regla general, detalla velocidades y DTL. Otoño superior saber es lo que permitirá la conversión entre uno o el DTO y el dominio. Entonces en lugar de mapear perfil, vamos a tener un constructor. Por lo que solo puedes ahorrar bañera CTO, tina que genera nuestro constructor. Y luego voy a tener una línea que diga Crear mapa. Y crear podría estar diciendo entre una fuente y un destino. Entonces T fuente sería, digamos que la solicitud de licencia sería mi fuente. Ese es el objeto de dominio. Leave request, DTO, y ese sería mi objeto de transferencia de datos. Muy bien, entonces estamos creando una configuración de mapeo entre la solicitud de licencia y la solicitud DTO y solo cerramos con los paréntesis. Y entonces puedo extender esto de nuevo y decirle que puede revertir MOP. Y último PR es variable para he visto aplicaciones donde la gente pone alguna cantidad de lógica de negocios en otoño arriba mismo cuando se trabaja con aplicaciones
complejas y probablemente cruzadas de dominios, probablemente
quieras un dominio o un detalle para poder convertir a un dominio objetos en un conjunto y un objeto de dominio en otro. Por lo que en realidad podría tener múltiples configuraciones de mapeo de un objeto a otro. También podrías crear convertidores personalizados para ver este miembro entra directamente en ese miembro coincidente del otro lado, hay una serie de cosas que puedes hacer con eso. Ese podría ser todo un curso por sí mismo. Pero hoy solo lo mantendremos sencillo con nuestros sencillos requisitos de configuración. Por lo que tenemos dejar una ubicación y luego tenemos el DTO coincidente. Y luego finalmente tenemos tipo de hoja. Ahora quiero señalar algo para realmente aludido a ello antes, pero quiero volver a mencionarlo. Hay momentos en los que se quiere conseguir un poco más granular o tener detalles específicos para un determinado propósito. Entonces echemos un vistazo a las solicitudes de licencia. Deja solicitudes detalle tiene bastantes campos. El propósito de un DTO es limitar el número de campos. Por lo tanto, reducir sobre la
publicación y están bajo publicación o proporcionar demasiada información al usuario. Entonces lo que estoy tratando de ver es que en caso de que se quiera ver una solicitud de licencia, entonces todos estos datos se vuelven relevantes. Pero entonces en el caso de que realmente solo necesites
enumerarlo o mostrar un listado de todas las solicitudes de licencia. Probablemente no necesites todos estos datos que el usuario no necesita
ver todos estos datos cuando están solicitando sólo la lista. Definitivamente no necesitarán ver los comentarios en ese punto. Probablemente no necesiten ver la fecha de acción aprobada o cancelada cuando están publicando. Entonces en ese caso, lo que tiende a suceder es que probablemente quieras romperlo un poco más. Por lo que a veces terminarías con una carpeta dentro de los detalles. Y esa carpeta sería específica para tal vez dejar solicitud. Y luego dentro de las solicitudes de licencia, tienes todos los detalles que difieren. Correcto. Entonces sí, deja solicitud detalle. Eso está bien. Este sería por los detalles qué bien, tal vez tengo otros detalles específicos para listar. Por lo que tendrías solicitudes lista D2, que sí, tendría el BSD TO también. Pero entonces tiene muchas menos propiedades en ella. Por lo que probablemente solo necesites hoja tipo la fecha que se solicitó y si no ha sido aprobada o no. Está bien. Entonces, una vez más, todo esto es relativo a lo que creas que necesitas proporcionar. Pero solo estoy viendo que en esta situación, probablemente no quieras poner cada cosa en
un solo detalle y luego usar siempre este detalle cada vez que se haga una solicitud, no importa cuán minúscula
sea su solicitud o cómo pocos datos que realmente necesitan en esa situación. Por lo que ese es el propósito de la DTO. Entonces en realidad con esos cambios, no lo
sé, rompí algún código. Vamos en primer lugar, permítanme actualizar el espacio de nombres en esta licencia solicita detalle. Entonces eso es todo sabe que es nueva ubicación y luego tengo actualizar mi mapeo para saber que tiene solicitudes de licencia, lista, DTO, arrancó un barco también. Así que solo adelante y actualízate esos. Y luego hagamos una compilación o construyo un exitoso. Lo último que vamos a hacer aquí es configurar en el método de registro de cobranza de servicios de
AI. Entonces el propósito de esto es, bueno, de acuerdo con la inyección de dependencia, queremos poder tener todos nuestros componentes, todos nuestros componentes inyectables definidos en lugar del nivel de aplicación. Pero entonces cualquier aplicación cliente puede seguir adelante y simplemente llamar al método y tenerlo registrado dentro de sí mismo. Cuando lleguemos ahí, lo verás, pero yo sólo haré esto bien? Y también esto serían aplicaciones, servicios, registro. Entonces esta va a ser una clase estática pública y va a tener
un método al que voy a llamar public static void Configure Application Services, que toma un parámetro de colección de servicios de IA. Por lo que podemos simplemente seguir adelante e incluir cualquier referencia que falte. Y luego dentro de esto llegamos a ver servicios dot add, auto, mapper. O diría que si estás familiarizado con dotnet Core y la inyección de dependencia, verías que esto es solo un servicio llamado acción que habrías visto en el archivo de inicio para cualquier aplicación de dotnet Core. Entonces la cosa es que lo estamos abstrayendo
solo a este proyecto para que cuando tengamos esa aplicación dotnet Core, solo
podamos llamar a este método. Y entonces seguiría adelante y registraría cada servicio que se define dentro de ese método. Entonces estamos agregando auto mapper y luego voy a decir punto de
ensamblado, conseguir ejecutando ensamble. Adelante y agrega cualquier referencia que falte. Ahora si estás familiarizado con la automática o has trabajado con ella antes, pero no necesariamente estás familiarizado con esto. Probablemente estarías más familiarizado con ver algo así como tipo de un entonces encontrarías el perfil de mapeo y entonces eso nos permitiría registrar este perfil tiene la configuración superior de otoño en general. El asunto con esto es que por cada perfil de mapeo que
tengas, probablemente tengas que repetir esta línea. Y tú, en función del tamaño de tu aplicación, puedes terminar con múltiples perfiles de mapeo porque he visto donde puedes tener perfiles de mapeo por objeto de dominio y pr,
pr detalle de objeto de dominio peering basado en el número de bases de datos son dominios que están presentes, ¿no? Por lo que incluso se encuentra en un nivel de aplicación, una aplicación o una aplicación cliente puede tener diferentes requisitos de Mapping a los de otra para que los mantenga separados. Entonces mi punto es que al decir ensamblado dot get ejecutando ensamblado, simplemente atravesará por cada perfil de mapeo que tenga esa herencia más o menos y solo funcionará. Está bien, no hay forma más fácil de verlo. Entonces así es como estamos registrando nuestro top otoñal en nuestra inyección de dependencia. Y eso es configurar mapeador otoñal en general. Entonces si construimos y es exitoso, entonces volvemos a continuación y continuamos nuestra configuración de aplicaciones.
8. Crea consultas con MediatR: Bienvenidos de vuelta chicos. En esta lección estaremos implementando dos patrones que nos
ayudan a promover el acoplamiento suelto a través de nuestra aplicación. Ellos son el patrón mediador y el patrón C QRS. Conocer el patrón mediador se ve como un patrón de comportamiento porque permite definir exactamente cómo interactúan un conjunto de objetos entre sí. En términos más simples, haces una solicitud y obtienes un resultado basado en tu solicitud. Cada vez que realices esta solicitud, puedes esperar este tipo de resultado que es una especie de consistencia que te ayuda a implementar. También te ayuda a obstruir toda esa lógica asociada a esa solicitud desde la aplicación de llamada. Ahora para ver patrón QRS y ver QRS es abreviatura de segregación de responsabilidad de comando y consulta. Te ayuda a separar las operaciones de lectura y escritura de cualquier data store. Entonces en el comando name y query es cualquier cosa que se vaya a aumentar los datos, cualquier operación de escritura, cualquier operación de actualización. Y una consulta soy yo leyendo los datos. Por lo que siempre puedes saber que cuando estás haciendo algo que va a aumentar los datos, es un comando. Si lees en datos es una consulta. Entonces empecemos. Vamos a pasar a nuevo get primero, y vamos a agarrar el paquete mediador, que es interesante, escrito por la misma persona que nos dio a todos el mapeador. Y ese es Jimmy BullGuard. Entonces vamos a seguir adelante e instalar eso. Y una vez hecho eso, vamos a volver a nuestro método Configurar servicios de aplicaciones y vamos a hacer algunos cambios aquí. Por lo que algunos de esos fueron olvidos de mi parte inicialmente, y pido disculpas. Entonces estamos cambiando esto de una voz a un servicio de IA llamado electrón, ese es uno. Y luego estamos sumando estas dos líneas. Estamos viendo servicios dot add mediator, assembly, dot gif ejecutando ensamblado, solo deja que el automapper y estamos devolviendo servicios. Por lo que para el plazo inmediato ADD, sólo vamos a seguir adelante e incluir las referencias faltantes. Y ahí vamos. Entonces así debe ser
este método de registro de servicio o cobro de servicios AI. Ahora que hemos hecho esa parte, solo retrocedamos y reunimos nuestros pensamientos y pensables lo que necesitamos hacer, necesitamos implementar los patrones PQRS. Por lo que el CQ son manchas son, y una vez más separa comandos de canteras. En otras palabras, necesitamos carpeta para comandos, necesitamos una carpeta para nuestras consultas. Ya sea Comando o consulta será manejado por lo que llamamos manejador. Entonces cuando haces una solicitud, se maneja y el manejador va a ser ya sea un comando para aumentar los datos o algo para devolver datos. Por lo que ven que hay bastantes partes móviles en este punto. Y es por ello que esto puede tener tantas opiniones sobre cómo se implementa. Entonces, una vez más, no estoy prescribiendo un método de implementación o estructura de carpetas, pero solo te estoy ayudando a visualizarlo. Podrás cambiarlo en función de tus necesidades. Pero esto es todo el mundo se fue a acercar tanto que crea una nueva carpeta dentro de o proyecto de obligación, lo
llamo características. Y luego dentro de las características, vamos a tener carpetas por tipo de dominio. Y la razón por la que digo tipo de dominio es que la característica de la aplicación es relativa a lo que vas a estar haciendo contra nuestro objeto de dominio contra las escrituras de éstos, ¿no? Entonces lo voy a estar haciendo en trozos basados la tabla o tablas características específicas que ofrece la aplicación. Entonces empecemos con uno simple como tipos de licencia. Dentro de características vamos a tener tipo de licencia. Voy a darme cuenta de este tipo de hojas. Y luego dentro de la carpeta tipos de hojas, voy a tener algunas otras carpetas. Voy a tener manejadores de solicitudes, luego dentro de los manejadores en cuándo tener comandos y consultas. Y esa es la estructura de carpetas con la que estaré trabajando. Ahora, como dije, opiniones difieren en espera. Podría verse una estructura polar. Algunas implementaciones en realidad tendrían el nivel superior para el maniquí en el nombre de la característica. Y entonces tendrían comandos y consultas. Y luego dentro de comandos o consultas, hay donde tendrían todas las solicitudes o tendrían una carpeta, lo siento,
por consulta, digamos dentro de la consulta, tendrían una carpeta para la consulta específica, digamos obtener tipo de hoja lista, esa será la consulta. Por lo que dentro de eso tienes la buena solicitud tipo hoja, obtén tipo de hoja requesthandler y el BTO específico a la misma. Por lo que una vez más, hay muchas maneras en que puede ver esto implementado, pero los conceptos siguen siendo los mismos. Simplemente quieres asegurarte de que puedes identificar comandos de manera diferente a tus consultas y sabes dónde están tus solicitudes. Las solicitudes son relativas a un 100. Entonces ahora que tenemos la estructura de carpetas en su lugar, empecemos con alguna codificación. Por lo que dentro de
las solicitudes, la primera solicitud que quiero es obtener la lista tipo hoja. Por lo que nombra sabio convención, siempre se quiere implicar
para qué es la solicitud o qué tipo de solicitudes en el neín, ¿verdad? Entonces consigue lista de tipos de licencia y voy a especificar solicitudes. Está bien. Por lo que obtener solicitud de lista tipo hoja. Y esta es una clase pública y va a heredar de las solicitudes de IO. Entonces esto es cortesía de mediador, y luego se va a preguntar, ¿qué debe esperar esta solicitud a cambio? Entonces cuando solicito usar este tipo de datos, ¿qué debo estar recuperando? Bueno, no deberías estar recuperando una hoja de lista tipo DTO, porque una vez más, entrarán los objetos de transferencia de
datos R1 y lo que nunca los objetos de dominio. Entonces esas son nuestras peticiones, sin embargo. Podría haber momentos en los que puede tener parámetros que pueden poner en solicitudes y así sucesivamente. Pero éste es uno muy sencillo. No voy a meterme en ninguna de esas complicaciones todavía. Entonces esa es nuestra primera petición. A continuación, necesitamos algo para manejar este tipo de solicitudes. Ahora se trata de una solicitud GET que lo hace de consulta. Entonces dentro de la sección de manejadores, voy a ir a la carpeta de consultas y voy a decir agregar una nueva clase y voy a llamar a este los manejadores de solicitudes. Entonces esa es mi convención de nomenclatura. Entonces tengo una solicitud por un nombre y luego acabo de anexar manejador. Por lo que vamos a seguir adelante y añadir esa como clase pública, que va a heredar una vez más manejador de solicitudes, cortesía de mediador. Y luego solicito manejador dice, Ok, lo que los solicita idealmente ancho, por lo que su solicitud son las solicitudes GET. De acuerdo, así que esa es la convención de nomenclatura que me gusta usar. Y más que eso, ¿ves mucho esa convención de nomenclatura porque entonces específicamente puedes atar nuestra solicitud a un manejador por eso de manera similar, una es la solicitud, otra es el manejador de solicitudes. Para que puedas seguir adelante e incluir cualquier referencia que falte. Entonces dice lo que solicita que mi manejo y qué debo estar esperando regresar. Por lo que el tipo de devolución de la solicitud debe ser el tipo de devolución. Has estado aquí. Por lo que se espera que regrese la licencia tipo DTO. Lo que enumeré fuera de la hoja diabetes. Está bien, así que ahora que eso está hecho, todavía
tenemos nuestra línea roja. Esta línea roja es porque necesitamos implementar la interfaz. Por lo que casi automáticamente, en realidad obtenemos un método aquí que dice manejado. Obtiene la solicitud como parámetro. Y entonces aquí es donde escribimos todo el código a manejar cada vez que entra esta solicitud. Ahora antes de empezar a manejar cualquier solicitud aquí tenemos algunas dependencias. Uno, necesitamos poder hablar con la base de datos. Ahora no hemos implementado nada, pero sí tenemos nuestros contratos de persistencia. Por lo que se trata de contratos que en realidad hablarán con la base de datos. Por lo que todavía no estamos interactuando directamente con el dominio aquí en absoluto. Muy bien, así que necesito inyectar las referencias faltantes. Entonces usando S3 o tina, tina, voy a conseguir constructor y luego voy a inyectar y dejo tipo repositorio. Entonces solo voy a seguir adelante y agregar cualquier referencia que falte. Y después haberla escrito en el constructor, puedo saber, decir crear y asignar un campo. Está bien, ahí vamos. Y tiendo a usar el subrayado porque me gusta ver el subrayado. Entonces sé que este definitivamente es el campo privado en la clase, así que esa es mi convención de nomenclatura. No necesariamente tienes causa ves que el código autogenerado no te dio un guión bajo, así que eso está bien. Ahora otra cosa que me gustaría inyectar es yo mapeador, porque sí necesito hacer algún mapeo cuando obtengo los datos de la base de datos, cuando este repositorio devuelve los objetos de dominio, necesito convertirlos a detalles para enviar el buck. Entonces necesito fabricante de automóviles también, así que soy superior, incluir referencias faltantes también ir adelante e inyectado o crea NSA en el campo. Y ahí vamos. Entonces tenemos todo inyectado y listo. Ahora para implementar este código de manejador, lo que voy a hacer es ejecutar una consulta contra el repositorio de tipo hoja. Entonces voy a decir var leaf fetch es igual a 08, dejar la terapia repositorio dot get all. Esto es una espera. Entonces eso significa que este método necesita ser asincrónico. Y luego verás que el único error desaparece al menos. Y entonces lo que necesitamos devolver es la lista de hojas tipo ETL. Entonces voy a decir retorno mapeador de punto mapa. Y entonces aquí es donde esto resulta útil en detalle tipo hoja, pero es una lista de hojas tipo D2 u otra. Y lo que voy a estar mapeando en eso será la lista de objetos de dominio que provienen de la consulta. Y ahí tienes. Todos están contentos. Entonces alguna vez solicito decir quiero las listas tipo hoja, entonces tenemos al manejador diciendo: Ok, puedo manejar esta solicitud por ti. Entonces a eso nos referimos definiendo el comportamiento de
la aplicación o definiendo cómo los objetos se relacionan entre sí. Esta solicitud siempre se relacionará con este cazador. Creo que si lo pruebas, múltiples manejadores para las mismas solicitudes, en realidad
te encontrarías con errores de tiempo de ejecución debido a alguna ambigüedad. Entonces así es como llegamos a definir claramente que cuando hiciste esta solicitud, siempre
puedes esperar el comportamiento. Ahora veamos otra solicitud y aún va a ser una consulta. Pero esta vez quiero una lanza. Tipo de hoja. Entonces estaba diciendo que puede ver solicitudes o puede terminar teniendo campos o propiedades dentro de sus peticiones que serán necesarias para manejar la operación específica. Entonces, ¿qué pasaría si quisiéramos conseguir el tipo elif, no toda la lista, sino el detalle tipo hoja. Entonces voy a crear otra pregunta. Y éste va a ser bueno. Dejar solicitudes de detalle tipo. Una vez más, recuerda hacerlo público. Ahora en esta situación, voy a sumar propiedad y voy a decir id Así que estamos obteniendo el detalle lo que significa que queremos un registro específico. Y la mejor manera de especificar un registro es enviando el DNI. Por lo que necesitamos un manejador para esta solicitud. Entonces voy a agregar ese manejador y la otra clase o obtiene el detalle de tipo solicita 100. Ahí vamos, hazlo público. No, un paso me perdí dentro de las solicitudes que necesitaba heredar de yo solicita. Y sólo está esperando una hoja tipo DTO una esta vez, ¿verdad? Tantas solicitudes DTO, adelante y cumplir con todas las referencias faltantes. Ahí vamos. Entonces el manejador ahora va a heredar de Solicito manejador y seguir adelante y agregar referencias faltantes. Se va a estar manejando solicitudes para buenas Solicitudes de detalle de tipo Leave, y se espera que devuelva tipo ETL. Entonces una vez que todas esas referencias faltantes se hayan ido algo, adelante e implementa la interfaz, y luego empezamos con eso. Ahora vamos a necesitar básicamente las mismas inyecciones que tuvimos que usar. Solo voy a agilizar eso y copiar y pegar ese código y simplemente cambiar el nombre
del constructor y seguir adelante y agregar todas las referencias faltantes. Y una vez que hayas hecho todo eso, puedes empezar con el código específico. Entonces en esta situación yo diría que var tipo de licencia es igual a y estamos con la llamada de método. Por lo que deja repositorio dot get y consigue su esperando una identificación. Por lo que tengo el objeto de solicitud aquí dentro del portal manejado métodos. Ahora puedo decir solicitud punto i e. Está
bien, otra vez, ¿dónde estamos enseñando? Entonces este espaciado, pero solo te estoy mostrando que así es como seguirías usando esos campos en tu consulta, en tu repositorio genérico o cercano, lo siento. Entonces cuando tienes métodos específicos definidos dentro del repositorio de tipo hoja, entonces puedes tener campos más específicos para tus solicitudes que se necesitan para manejar ese tipo de operaciones. Entonces una vez que logramos eso, lo siguiente que tenemos que hacer es devolver los objetos DTO tipo hoja. Entonces diré mapeador, mapeado en detalle tipo hoja y estamos mapeando el tipo. Entonces una vez más, sólo detalles. Ahora una cosa a tener en cuenta es que en los manejadores que tienen una clara separación entre los comandos y las consultas. Pero en las solicitudes no hay separación clara. Entonces cuando las solicitudes comienzan a crearse para los comandos, tenemos que confiar en nuestros ojos. Tenemos dos OK. No estamos cansados para que no nos confundamos en cuanto a qué petición es el agua. Y no creo que eso sea, es muy eficiente. Entonces voy a tener comandos dentro de mis solicitudes, y también voy a tener consultas. Entonces sé que cada vez que quiero alguna petición, tristeza, e indagaciones, sé exactamente a dónde ir. Y lo mismo para los comandos. Entonces como dije, son estructura de carpetas diferentes. Algunas personas una vez más acabarían de decir tipos de licencia. Y entonces habrían tenido los comandos. Y luego en lugar de los comandos que tendrían los diferentes comandos con todos los recursos necesarios para ese comando específico, el detalle, el manejador, la solicitud, todo en esa sub carpeta. Entonces a medida que rompes este inodoro que vas a necesitar más archivos, más carpetas porque quieres ver una separación clara tanto como sea posible. Una vez más, dijo que esto se implementa es relativo al creador. Entonces solo voy a mover mis consultas que he creado hasta ahora a esa carpeta específica. Y por supuesto, después de actualizar ese espacio de nombres. Y una vez que haga eso, voy a seguir adelante y actualizar mis manejadores para conocer la nueva ubicación de sus solicitudes correspondientes. Entonces con todo eso, amanecer, voy a hacer una construcción y construir fue exitosa y ya ves cómo se está uniendo todo. Entonces si quieres, puedes seguir adelante e implementar las otras características que empezamos con los tipos de hojas. Se puede al menos implementar las diferentes, las dos leídas o las dos operaciones de consulta relativas a asignación de licencia y relativas a solicitud de licencia.
9. Finalización de las consultas para MediatR: Bienvenidos de nuevo chicos que siguen en la misma línea de configurar nuestras consultas para nuestras características adicionales. Por lo que ya pasamos por hacerlo para tipos de hojas. Y la asignación era hacerlo para solicitudes de licencia y asignaciones de licencias. Entonces ya lo he hecho y solo te estaré caminando. Entonces si no lo has completado,
iré lo suficientemente despacio y te
explicaré todo lo que estoy haciendo para que puedas replicarlo. Y si no, entonces solo podemos comparar notas y siéntete libre de
avisarme si has hecho algo diferente a como lo he hecho. Entonces el primero, Empecemos con asignaciones de licencias. Entonces tengo las consultas y tengo el, lo que tengo los manejadores y las solicitudes, y tengo las consultas en cualquiera de ellas. Ahora siguiendo el estándar hasta ahora verías que o las misiones se ven bastante similares a lo que parecían para unos tipos de hojas. Tenemos la solicitud detallada de asignación de licencia de get, que se lleva el DNI. Y también tengo uno para la lista. De acuerdo, así que en la consulta es, tengo una ligera sorpresa para ti. No sé si lo hiciste de esta manera, pero te guiaré por exactamente lo que se ha hecho de manera diferente. Entonces por supuesto estamos incluyendo el hola correcto, El repositorio de asignación de licencias en lugar de opuesto
al repositorio tipo hoja porque estamos tratando con ubicaciones de Levi derecha. Ahora en cuanto a nuestro manejo, verías que aquí tengo un método que no pasamos en nuestro,
en nuestra configuración de repositorio. Tengo asignación de licencia de get con detalles. Conoce el propósito de mí especificando esto es que cuando obtenemos los detalles de la asignación de hojas y si necesitas un recordatorio o dejar asignación en realidad tiene una propiedad de navegación de tipo hoja, lo que significa si quería show Qué licencia tiene, qué número de b después, mostrar el nombre de ese ícono de la hoja, mostrar el DNI que es inútil, ¿verdad? O el cliente u otro controlan el id, necesitarían alguna cantidad de detalles del tipo de hoja de su lado. Entonces cuando digo con detalles, el propósito de ese método es hacer que
incluya esa propiedad de navegación y todo para que para cuando llegue pero que deje asignación, tendría toda esa lógica no están listas y todo lo que tengo que hacer es mapear y regresar. Entonces en este punto solo voy a hacer una pausa y 0 que verías patrón de
diseño a veces donde realmente
hacen toda esa lógica compleja aquí mismo en el manejador. Entonces he visto donde realmente se conectarían directamente al contexto aquí en el manejador. Y luego hacer todas esas consultas crudas justo aquí en el manejador y luego masajes y luego finalmente devolver lo que necesitan para regresar. Entonces ese es un patrón de diseño que podrías ver. Y el otro es donde abstraemos todas esas lógicas y complejas consultas y lógica empresarial. Y luego mitos para el repositorio. No, no digo que uno sea mejor que el otro porque
tuve el enfoque tiene sus pros o contras en cuanto hacer métodos que específicamente se ocupen
de un escenario como conseguir la asignación de hojas con los detalles. En términos de eso, podría ser bueno poner eso en nuestro repositorio, un método donde se tiene una referencia directa a dónde ese arte de lógica atrás tipo de operación porque es está sucediendo
ese arte de lógica atrás tipo de operación porque esposible que necesite reutilizar ese mismo tipo de lógica en múltiplo manejadores. Por lo que eso en realidad reduciría la repetición del mismo tipo de consultas y del mismo tipo de inclusiones y todo a través de múltiples manejadores. Si solo lo tienes en un solo espacio de repositorio. El inconveniente de los repositorios, sin embargo, es que por lo específicas que pueden llegar las cosas? Sí, tenemos las cosas genéricas, pero obviamente esto no es un comando genérico que cada característica nuestro dominio me objeto, use de la misma manera. Tenemos que tener un método específico y entonces probablemente vamos a terminar por un agujero de conejo de tener muchos métodos específicos en nuestro repositorio. Entonces ese es uno de los sitios don't, el patrón del repositorio sabe, como dije, si haces todo aquí en el manejador, funcionaría. Pero una vez más, los inconvenientes de eso es que podría necesitar
repetir ese tipo de operación a través de múltiples manejadores. Y luego terminas repitiendo código en múltiples lugares. Y entonces la modificación podría llegar a ser difícil a largo plazo. Entonces esa es la sorpresa Alpha. Entonces si echan un vistazo a nuestra interfaz, verían aquí que en realidad tiene tanto para la lista como para el individuo. Ahora el jurado está fuera sobre si necesitas ambos. El motivo por el que incluí el 14 y la lista, por supuesto, es que en la lista, las asignaciones de licencia, quiero mostrar el nombre de la licencia y el d,
El nombre de la licencia y el nombre del tipo de hoja muerta y el dy. Por lo que necesitaría incluir aquí los detalles. Y luego si estás viendo uno de ellos, te gustaría ver los detalles también. Así que acabo de hacer eso e hice lo mismo. Y cuando estás trabajando con muchos de nosotros, necesitas navegar rápidamente. Entonces solo voy a usar esta flecha azul arriba aquí para sincronizar tienda este documento es rápidamente y luego dejar solicitudes. Ya ves que tengo métodos similares porque en las solicitudes de licencia necesitamos saber qué tipo de licencia se está solicitando. Y si estoy viendo la lista, te gustaría ver este tipo de hojas se solicitó en esta fecha, etcétera. Está bien. Ahora bien, en cuanto a nuestras solicitudes de licencia, tengo otra sorpresa de diapositiva y espero que ustedes se hayan pillado y ya lo hayan hecho. Pero las consultas se ven bastante iguales. Pero en términos las solicitudes más bien, pero en cuanto al tipo de devolución, notarías que tengo solicitud de licencia solicitud detalle mostrando las solicitudes de licencia DTO, sin embargo, para la lista y discutimos por qué separaríamos los detalles antes. Contamos con solicitudes de licencia detalle de lista. Por lo que la lista está determinando una lista de los detalles especializados para la lista. Y entonces los detalles está devolviendo el detalle con mucho más detalle en él. Para las consultas. Preocupaciones similares por la lista de solicitudes de licencia, manejador de solicitudes. Por supuesto que está devolviendo la lista de solicitudes de licencia DTO. Y el manejador luce palabras bastante similares llamando a un repositorio de solicitud de eliminación y llamando a las solicitudes de licencia get con detalles similitud. Cuando estamos viendo el manejador de detalles, es
lo mismo excepto que estamos regresando solo el detalle de las solicitudes de hoja, el laboratorio configurando esto, podrías haber notado que estás obteniendo muchas líneas
rojas cuando 're tipos desemparejados. Y si tuvieras el tipo de datos incorrecto aquí o lo incorrecto solicitaría que se hiciera referencia al tipo, todo se rompería. Entonces es muy, muy estricto. Si me dijo que la solicitud está esperando solicitud de tipo de licencia DTO, no
puede poner ningún otro tipo de datos aquí en ese manejador que le está diciendo debe atender esa solicitud. De acuerdo, así que puedes ser muy,
muy cuidadoso con eso. Y una vez que te acostumbras al patrón, estas cosas vendrán de manera más natural. Sólo puedo asignar si inicialmente es un poco frustrante. Pero una vez más, tienes el código al que hacer referencia para que siempre puedas simplemente pausar cuando necesites y replicar estos bits de código en tu aplicación en consecuencia. Ahora en nuestra siguiente lección, vamos a ver cómo configurar nuestro primer comando. Y el comando una vez más aumentaría los datos en la base de datos. Entonces vamos a ver lo que se necesita para configurar, crear comando para cualquiera de nuestros objetos de dominio.
10. Crea comandos con MediatR: Bienvenidos de vuelta chicos. En esta lección vamos a estar echando un vistazo a configurar comandos. Por lo que los comandos vuelven a aumentar los datos y
vamos a estar empezando con o crear comando. Ahora si estás mirando mi Explorador de soluciones, notarías que tengo algunos archivos más y tengo una carpeta D2L reestructurada. Entonces déjame simplemente colapsar todo lo demás para que puedas enfocarte en esa sección. Por lo que en las primeras etapas de planear este tipo de arquitectura, siempre
vas a estar cambiando las cosas porque es bueno hacerlo bien desde null a diferencia de más adelante cuando tienes muchos archivos diferentes y más, para instancia, las actualizaciones cuando se mueve, estos otros archivos son propiedad. Por lo que en las primeras etapas de configurar los detalles, había indicado que probablemente querrías tener una carpeta para los detalles y luego tener los diferentes tipos de detalles ahí dentro. Entonces lo hicimos con las solicitudes donde teníamos las solicitudes de licencia D2 y eliminar solicitudes lista detalle en lugar dejar carpeta de solicitud. Por lo que acabo de extender ese concepto a los otros detalles donde tengo una carpeta de asignación de permisos y carpeta tipo elif y nombre a esta hoja ese detalle profundo. Permítanme que lo corrija. Por lo que dentro de estas carpetas, vamos a tener los diferentes detalles. Y una vez más, no es absolutamente
necesario que tenga múltiples detalles o detalles específicos de un propósito. Pero les voy a mostrar por qué es beneficioso hacer eso a veces. Por lo que con el tipo de hoja, el riesgo es bajo. Tenemos detalle de hoja. Todo lo que requiere es un nombre y el número predeterminado de días. Eso para mí, eso es simplemente suficiente. Este dato corre muy poco riesgo de
sobreexponer cualquier cosa para cualquiera de las operaciones que podemos crear fácilmente usando este detalle, podemos listar fácilmente y podemos mirar los detalles. Es muy sencillo. No obstante, con las solicitudes de licencia, habíamos discutido que las solicitudes de licencia DTO tiene mucho más detalles en ella. En una configuración de lista, no
necesitamos tantos detalles. En realidad solo necesitas los detalles del tipo de hoja solicitada, la fecha en la que se solicitó, y si está aprobada. Ahora en el Create, una vez más no necesitamos pedir al consumidor que proporcione todos esos detalles. Porque si comparas solicitudes de permiso de creación de dientes, realmente no necesitamos la opción de fecha. Y cuando alguien está creando una solicitud de licencia, cuando estoy pidiendo una licencia, no
hay acciones de fecha. Por lo que no hace falta que se proporcione eso. La fecha solicitada que puede ser puesta por nosotros, por el sistema. No necesitamos obtener eso del usuario ni del consumidor. El inicio y la fecha de fin corto. Esos son esenciales. Necesitamos conocer el tipo de hoja. No necesitamos conocer todo el objeto del tipo de hoja. Sólo necesitamos el identificador del que se está solicitando. Y en ese punto, no está aprobado ni cancelado. Por lo que puedo tener un detalle específico y como estoy hablando, estoy viendo que tengo extra fusionando esto, pero tengo un crear leave requests DTO,
que va a tener la fecha de inicio,
la fecha de fin, el identificador para el die de hoja siendo solicitada. Y una vez más, el sistema puede ver la fecha solicitada. Y necesito hacer de esto en realidad un nullable. Entonces voy a aprovechar esta oportunidad para ajustar esto. Entonces esto necesita ser nulable, pero no necesito al remitente en el Creates. Yo lo tomo todo junto, creo en la solicitud de licencia, voy a hacer que sea anulable porque regla de
deducción realmente significa cuándo fue aprobada o cancelada. ¿ Verdad? Y entonces de igual manera, solo voy a hacer esto hasta el dominio. Una vez más, es bueno ver estas cosas temprano y ajustarlas porque aún hicimos la base de datos, así que no tenemos que preocuparnos de que esto se desgarre demasiado. ¿Todo bien? Entonces por eso tengo un DTO específico para crear la solicitud de licencia, diferente al listado, diferente a los detalles. En otro, cuando tenemos la asignación de licencias y desasignación tiene una serie de éstas, los detalles del tipo de hoja que se relaciona con ella, identificador y el periodo. Es similar a la solicitud de licencia. No necesito los detalles del tipo de hoja al tipo de momento de creación. Entonces cuando hablamos de sobre la publicación, significa que estamos dando a la aplicación cliente la oportunidad de proporcionar demasiados datos. Y luego aquí es donde hackear y malos datos y personas introduciendo anomalías en tu base de datos, así es como eso sucede. Por lo que esta es una buena manera de restringir lo que puede suceder en una operación. Entonces sepan eso. Tener una buena comprensión de por qué tenemos más detalles introducidos. Echemos un vistazo a los comandos. Entonces voy a empezar con el más fácil,
que son los comandos de tipos de hojas. Voy a ir a solicitar y voy a crear una nueva clase. Y este Gaumont va a ser muy específico crear solicitud tipo hoja. Entonces esa es la petición de crear un tipo de hoja y se fue a seguir adelante y agregarla y convertirla en una clase pública. Y entonces éste está heredando como sabemos de yo solicito. Y volverá, voy a hacer que devuelva un entero 0. Este entero será. el nombre o lo siento, ha creado
el nombre o lo siento,el ID del valor o el registro. De acuerdo, así que creas, solo te vamos a decir la identificación de lo que lo creas. No sabemos qué puede necesitar hacer el cliente después de la creación, pero les estamos dando pero la ID guardada, necesitan ir a la página de detalles después. Eso depende de ellos, pero les estamos diciendo que fue exitoso. Aquí está el DNI para el nuevo registro. Ahora en el comando, lo que vamos a tener, como sabemos mi nulo es nuestro manejador de coincidencia para esta solicitud. Por lo que heredamos de solicito manejador. Y solicito manejador va a estar implementando la solicitud de crear tipo hoja. Adelante e incluye cualquier cosa que falte. Y verá que está devolviendo un entero. Ahora cuando implementemos la interfaz, verás que conseguimos que esa tarea devuelva un entero y nuestro manejador. Ahora volvamos a saltar un rato a sus peticiones. Y hay pocos patrones que podrías ver en la solicitud de creación. Un patrón es que la gente realmente escribiría todos los campos que cuando estás a punto de crear un registro para este año, enviando las solicitudes para crear registro para ese tipo. Pondrían en los campos en la solicitud real para ver estos son los honorarios que se te permite enviar con la solicitud. Y entonces en ese momento, esa solicitud sirve básicamente al propósito de mi detalle que acabo de definir aquí. No, yo personalmente, no me gusta mezclar y emparejar. No me gusta tener detalles aquí, pero entonces cuando es yo creo, tengo los campos aquí. Y entonces, ya sabes, no sé a dónde ir y
necesito cambiar lo que va a veces no recuerdo. En cambio, mantengo todo a nivel de detalle y la solicitud es realmente solo un mecanismo para transferir los datos. Por lo que el DTO representa los datos y la solicitud es justo ese transporte. Con todo lo dicho, voy a presentar nuestro inmueble en esta solicitud de licencia tipo DTO. Por lo que este inmueble es lo que el consumidor llenará con la solicitud y la enviará. Entonces en nuestro mando sabemos que decimos solicitar diabetes de hoja de punto, ahí es donde están los datos. Entonces por supuesto, si vamos a estar interactuando con tipos de hojas y automapeador, entonces necesitaremos que nuestros sospechosos habituales en nuestro constructor sean inyectados. Y para la velocidad de nuevo, esos vuelven a uno de los manejadores existentes y solo copian y pegan, cambian el nombre del constructor. Y luego solo incluimos cualquier referencia que falte. Está bien, para trabajar más inteligente, no más duro. Entonces ahora que tenemos todas las herramientas que necesitamos, ¿cómo configuramos nuestro manejador para crear este registro? Pero antes de seguir adelante, voy a hacer un ligero ajuste. Entonces otro patrón que verás, y creo que voy a usarlo esta vez sólo porque es para mí,
es más limpio en lugar de solicitudes. Entonces cuando estamos lidiando con comandos, no, no
va a ser nuestra petición porque yo solicito es cuando estás pidiendo algo, ese comando es cuando estás diciendo algo. Quieres un mando. Entonces en lugar de nosotros usando solicitud en el nombre aquí donde decimos crear comando tipo hoja. Muy bien, Así que al cambiar el nombre de la fuente, puedo cargar el IntelliSense para renombrarlo en todo el tablero, pero renombraré el archivo manualmente. Por lo que tenemos crear comandos tipo hoja, así que sabemos con certeza que éste es un comando y es obviamente el manejador se supone que está llevando todo su comando. Entonces Comando Entrar, está bien, y actualizar cualquier otra referencia está en el lugar. Entonces creo que en realidad es más limpio y más fácil en los ojos. Es un distinguido entre lo que solicito clases sobre lo que nuestras clases de mando resuelven para nuestra operación. Lo que vamos a hacer es definir el tipo de hoja a ser igual. Y luego solo vamos a usar auto mapper para mapear en tipos de licencia. Por lo que estamos mapeando desde el detalle hasta el objeto de dominio esta vez el nuestro. Por lo que mapeador Dartmouth tipo de hoja, entrelazado tap nuestra mirada a petición punto hoja tipo BTO. De acuerdo, así que solo sigue adelante e incluye cualquier cosa que falte. Ahí vamos. Entonces ahora decimos que el tipo de licencia es igual para conseguirme la versión trapeada de eso en el objeto de dominio. Entonces llevamos a cabo nuestro, esto va a decir tipo de licencia es igual a y nuestros pesos en vamos a llamar a nuestro repositorio tipo hoja dot add method blocks, ¿verdad? Entonces recuerda que en realidad está devolviendo el objeto o algo del mismo tipo de datos, ¿verdad? Entonces deje tipo ahora se va a actualizar porque después de Entity Framework, que es lo que vamos a estar usando como nuestro RM. Después de que haga su operación se va a actualizar el ID. Por lo que estamos devolviendo el objeto con ID actualizado y sabemos que tenemos esa ID. Podemos decir retorno, tipo de
licencia, ID de punto. Ahí vamos. Entonces sepan que se ha manejado el mando. Nolan, lo
miramos, vemos que realmente no fue tan complicado de hacer. Son solo tres líneas donde obtener la solicitud con los datos. Y luego lo vamos a mapear a los objetos de dominio. Vamos a entonces jefes o dentro de un repositorio o para que se produzca la operación. Y entonces sólo estamos devolviendo la idea y eso es todo para el comando create leaf type. Por lo que en realidad puedes simplemente hacer una pausa aquí y pedirle que lo haga con los demás. Yo lo voy a hacer y luego podemos comparar notas. De acuerdo, así que me he saltado adelante y he ido adelante e implementado los comandos que crean comandos para los otros dos objetos de dominio. Entonces si lo miras con cuidado, ves que es más o menos la misma cita aparte de los nombres y los repositorios involucrados, es más o menos el mismo código. Entonces este es el manejador de comandos leave allocation. Puedes hacer una pausa, puedes replicarlo si es necesario. Pero ese es nuestro creador manejador y nuestra búsqueda de carrera. Simplemente tomando que crear dejar detalle de alegación en lugar del detalle de alegación de licencia. Está bien. De igual manera para la solicitud de licencia, mismo código, misma estructura, ¿no? Y luego el comando, solo
está tomando el detalle de solicitudes de licencia para crear el detalle de solicitud. Entonces ves que todo este tipo de luce muy similar. Para que puedas seguir adelante y replicar los de tu código. Y cuando regresemos, veremos los otros comandos que incluirían actualizar y eliminar.
11. Terminar los comandos con MediatR: Muy bien chicos, bienvenidos de nuevo. Como notaste, mi pantalla está en blanco. En esta lección, vamos a estar hablando de agregar los manejadores de actualización y eliminación y todos los activos que van con ellos. Entonces mi pantalla está en blanco porque he agregado bastantes activos y voy a
pasar por ellos uno por uno contigo y puedes seguir adelante y replicarlos. Pero quiero que entendamos las decisiones que estamos tomando en este punto ya que son decisiones críticas. Y este tipo de arquitectura, las cosas que pones ahí, todo basado en decisiones. Una vez más, son relativos a lo que estás trabajando, tu equipo y a la aplicación general sobre lo que esperas lograr. Entonces, empecemos mirando los detalles. ¿ Dónde están? Pasó por los detalles y tipo de los separamos por carpetas para que podamos ver todos los detalles relativos a un tipo de dominio con bastante facilidad. Pero entonces en este punto, teníamos un VT0 para el tipo de hoja, y habíamos dicho que, vale, eso era de bajo riesgo porque podía ser utilizado para muchas operaciones diferentes. Desde entonces lo he roto en dos. Y la razón de esto es que has creado hoja tab2 diferente a la hoja tipo D2 y todo. ¿ Por qué? Debido a que el detalle tipo hoja hereda del detalle base y la base D2, recuerda nos da el ID, conoce el riesgo de esto. Y una vez más, propósito del detalle es reducir tipo de lo que llamaremos sobre la publicación. Si estoy creando un tipo de hoja, no
necesito una identificación. No quiero darle al consumidor la capacidad de
proporcionar una identificación porque eso solo daría problemas. Les estoy dando exactamente lo que necesitan para superar su operación. Por lo que creé un nuevo detalle para tipo hoja donde solo obtienen nombre y escrituras por defecto. No pueden proporcionar un campo de identificación. Detalle tipo hoja se puede utilizar para todo lo demás,
para editar, para ver porque bueno, tiene esos campos así como BCE, que es el ID. Ahora, como puede terminar obteniendo más y más detalles y tienes sensación repitiendo a través de los diferentes detalles, entonces tal vez quieras considerar tener una carpeta común dentro de esa subcarpeta ya para tipo de definir esta propiedad es que este detalle debe tener de todos modos. Por lo que cualquier hoja tab2 que surja más hafnio y debe tener días por defecto. Podrías definir una clase base si lo necesitas. De acuerdo, ahora podemos pasar a las asignaciones de licencias tener tres detalles de asignación de licencias en este punto, y voy a señalar un error que cometí en uno de ellos. Este error fue tener crea detalle de asignación de licencia heredando de este detalle. Está bien, así que hay que tener cuidado con estas cosas si estamos tratando de ser estrictos. Entonces eso fue un error de mi parte. Crear detalle de asignación de licencia una vez más no debe tener absolutamente ninguna referencia a ninguna clave primaria en absoluto. Pero entonces sí necesitamos los otros campos. Las actualizaciones, sin embargo, sí necesita acceso a la DTO base para nuestros propósitos de actualización. Ahora, podría ser que dijimos, vale, bueno, una vez más, crear ese detalle base del que todo el mundo hereda. O podríamos simplemente morder la bala y decir usaremos 14 crear o actualizar si se proporciona el ID y sabemos que es una actualización si no se previene y asumimos que es yo creo, esos podrían ser fácilmente argumentos que no estoy viendo, no, no estoy viendo que sí. Depende de lo granular que quieras
obtener y estas son tus decisiones que debes tomar en base a tu contexto. Solo estoy señalando las diferencias y los riesgos en consecuencia. Entonces los voy a estar sacando así. No Por solicitud de licencia pasa incluso por otro nivel. Por lo que sí tenemos el detalle de solicitud de licencia donde familiarizado con eso. Tenemos el detalle de lista el cual ya estableció por qué eso es diferente. Tenemos el Create que una vez más es incorrectamente, al
menos en mi contexto heredando de esto, que voy a caracterizar nulo. Y entonces tengo que haber actualizado el Detalle de la solicitud diferente de licencia cambiada solicitar detalles de aprobación? No, vas a preguntar. Está bien. Entonces, ¿por qué tener ambos? Porque ambos están hablando de aumentar los datos. Está bien. Bueno, una vez más, es cuestión de host engañado quieres ser
por lo que la actualización sirve para el propósito de permitir que el usuario o el consumidor permita al usuario final actualizar sus solicitudes. Querían tal vez cambiar las fechas de inicio o el final
tal vez eligieron vacaciones cuando esto debió haber elegido enfermo. A lo mejor quieren poner nuevos comentarios o simplemente quieren cancelarlo. Entonces les estoy dando exactamente lo que pueden hacer usando este DTO si envían su solicitud para actualizar. Estas son las únicas cosas que se pueden actualizar. No obstante, aprobación de licencia de cambio. Solicitar, perdón, dejar solicitud de aprobación detalle, lo siento, tendría sólo la capacidad de cambiar. Está aprobado DSR null. Entonces el aprobador en realidad sólo está diciendo que sí o no. Es decir, si tuvieras más campos como comandos adicionales y cualquier cosa que pudieras agregarlos a DTO. Por supuesto, tendrían que ser presentados los objetos de dominio. Pero mi punto es que estoy usando el detalle aquí para ayudarme a hacer cumplir ciertas reglas de negocio y ciertos comportamientos que mi aplicación es capaz. Y, y una vez más, he visto situaciones donde hay un plano D azulado y se toman decisiones en el 100 que en base a los datos presentes, tal vez en la solicitud estén al detalle. Este es el tipo de operación a realizar. Por lo que depende de cuánto quieras romper ETL para tener ese nivel de granularidad. Entonces ya saben, si se trata de una aprobación solicitada, sepan exactamente a qué manejador acudir. O puedes tener un manejador de comando grande que está tomando los datos y un montón de sentencias si para ver si es, si el ID está presente, entonces si no está presente, entonces sí, Pero entonces si está presente y esta bandera no está nulo, entonces asuma que es una aprobación. Podrías hacerlo de esa manera, pero yo no lo estoy haciendo de esa manera. Prefiero saber que cuando se trata de una solicitud de aprobación, tengo ese comando de aprobación de cambio. Si se trata de una actualización, es un comando de actualización y saber exactamente a dónde ir para hacer qué. Entonces ahora que tenemos esa explicación detallada fuera del camino, voy a saltar a las características,
carpetas en futuros, en asignaciones de licencias y tipos de dejar
al menos ya he definido los nuevos manejadores y sus comandos. Entonces echemos un vistazo a la más simple. Por lo que tenemos el comando update leave type. Y este comando para el tipo de hoja
solo está tomando nuestras peticiones están heredando de Eric quest como sabemos, pero luego está devolviendo lo que llamaremos una unidad. Entonces si simplemente pasas por alto, necesitas ver que se trata de un
constructo provisto de mediador que no representa nada como vacío, ¿verdad? Sin contenidos. Entonces en el diseño de API, cuando haces una actualización, normalmente
regresarías a 202, si no me equivoco, lo cual es abreviado de ningún contenido. Entonces significa que fue exitoso, pero no tengo nada que mostrarles. Eso es básicamente lo que es la unidad. Y luego estamos tomando esa hoja tipo DTO como propiedad. Todavía no he implementado los comandos en los manejadores, así que podemos hacerlo juntos. Solo estoy demostrando que tenemos
ese mismo constructo para el comando update leave allocation, donde estamos tomando el detalle de asignación de licencia de actualización y devolviendo esa unidad. Y tenemos ese comando definido en consecuencia, también vacío. Entonces vamos a hacer esos dos juntos porque esos son bastante simples. Y luego vamos a pasar algún tiempo explorando las solicitudes de licencia y las reglas de negocio ahí. Ahora el flujo de trabajo para nuestro manejador, y voy a empezar con el manejador de comandos tipo hoja. Muy bien, el flujo de trabajo aquí es que necesitamos querer recuperar el registro original para actualizar ese origen se requieren y luego tres, enviarlo todo a la base de datos y luego devolver la unidad, o al menos algo para decir que era exitoso. Por lo que dos enfoques. Uno, se puede utilizar el repositorio para tener ese método específico porque entonces en el caso de las solicitudes de licencia, podría
haber métodos específicos. Y luego una vez más, vas a bajar ese juguete de conejo apagado. Tener métodos muy, muy específicos en cada repositorio a lo largo de la línea. O simplemente puedes hacer la mayor parte del trabajo dentro de un manejador, que es para lo que sirve de todos modos. Está bien. Entonces solo voy a decir var tipo de licencia es igual a dejar repositorio de tipo, Git. Y luego estamos buscando en la solicitud, buscando en la hoja para estar mirando el DNI. Ahora, otro patrón de diseño que he visto es cuando es un comando de actualización tipo hoja, usarían el tipo de hoja regular, digamos el que no tiene el ID, pero luego poner la propiedad ID dentro de la solicitud o el comando objeto para que nosotros, cuando usted está haciendo la actualización para incluir el ID dentro de este objeto. Y entonces el detalle es justo en sí mismo. Hay tantas maneras de hacer esto. Y una vez más, los que entiendas lo que estás haciendo, me pueden hacer la mejor implementación en base a tu contexto. Aquí. El tipo de licencia se va a recuperar en base a la identificación fuera de la carga útil que entra con la solicitud. Y entonces podemos ver mapeador no MOP. Y luego mapeador dot map es más o menos sólo va a, en esta situación, obtener la solicitud pensamiento hoja tipo D2. Y note que no estoy especificando, necesito teclear esta vez. Estoy usando paréntesis, mapa de puntos mapeador, paréntesis abiertas. Y entonces estoy viendo que esta es la fuente de los datos. Y quiero que el tipo de hoja que acaba de ganar de la base de datos sea el destino de los datos. Y estoy consiguiendo esa línea verde porque fallé A ella en la línea. Pido disculpas. Entonces ahí vamos. Entonces mapper dot map y luego lo ve por favor solo actualiza lo que esté a la derecha con lo que esté a la izquierda, eso podría ser diferente si es diferente o no, esto, por favor actualízalo porque la actualización se va a enviar de nuevo. Y es por eso que nuestro detalle necesita tener tantos campos que tanto los datos,
el objeto de dominio en sí como sea posible. Está bien. El nombre de Dava va a tener días por defecto. No sabemos qué ha cambiado, así que por eso estamos viendo el otoño superior, solo actualizar todos los valores. Si ese Blanco el nombre, entonces lo vamos a actualizar a un nombre en blanco. Ojalá no lo hicieran. No obstante, si no cambiaron de nombre, entonces la expectativa es que el mismo nombre vaya a volver. Entonces, una vez más, no podemos dar cuenta de lo que pudo haber sido la barbilla. Por lo que solo estamos viendo, por favor actualice el tipo de hoja con los valores correspondientes provenientes del objeto de la izquierda. Y luego vamos a ponderar nuestra actualización de repositorio neve. Y entonces aquí es donde enviamos nuestro mapeo de postes tipo hoja o enviándolo a la Actualización. Y luego solo devolvemos valor de punto unitario. Y eso es todo. Esa es nuestra operación de actualización. Bueno, tengo esta línea roja aquí arriba porque tengo int y no unidad. Entonces después de mí ese cambio, todo está bien. Entonces eso es para la obesidad en el tipo de hoja o qué? El tipo de hoja. Entonces en realidad sólo voy a copiar esto. No me voy a dar demasiado trabajo. Voy a saltar para actualizar asignación de licencias. Y lo único que vamos a estar haciendo de manera diferente aquí es que en lugar de usar el repositorio tipo hoja, voy a estar usando el repositorio de asignación de licencias. En lugar de ver hoja tipo DTO, estoy viendo asignación de licencias BTO. Y en lugar de llamar al tipo de hoja de objeto, lo
estoy llamando asignación de permisos, todo lo demás es bastante estándar y casi igual. Y esto manejará nuestra solicitud de actualización. De acuerdo, así que he ido adelante y completado los comandos leave request para actualizar LaCo, vemos no que no sea tan complicado o así he ido adelante y he hecho el comando update leave request y el manejador correspondiente. Por lo que nuestra licencia solicita manejador de mando tomado de la unidad de devolución de mando. Y es sólo conocer la diferencia una vez más, es el repositorio que se está utilizando, pero es prácticamente la misma operación. Ahora una cosa que tal vez quieras considerar son las reglas de negocio específicas, nuestras propias este tipo de operaciones. Entonces sí, el código, se ve igual, pero luego al actualizar una solicitud de licencia, podría
haber otras cosas que tengan que suceder. Correcto. Por lo que en el caso del cambio, solicitar, cambiar y dejar solicitar aprobación donde solo obtenemos aprobación o no. También necesitamos establecer la acción que también necesitamos para actualizar probablemente algunas otras cosas. Entonces creo que serás bueno si tuviéramos una función específica en nuestro repositorio para manejar la solicitud de cambio. Ahora lo genial de las solicitudes es que no necesariamente tenemos que
tener nuestra solicitud por hora solicitudes por todo el tiempo. En realidad podría reutilizar la misma solicitud y manejador para manejar este tipo de operaciones. Entonces veamos esta situación. Por lo que dentro de la actualización, dejar, no dejar asignación, disculpas, dentro de la licencia solicita comando, podríamos tener las solicitudes de licencia DTO, pero también podría tener una propiedad de tipo cambio de licencia solicitar aprobación DTO. Por lo que esta solicitud es capaz de tener alguno de estos objetos. Ahora en el manejador, puedo tomar una decisión y llamar al método apropiado en
base a esto porque sigue siendo un comando de actualización, ¿verdad? Por lo que dentro de este manejador de comandos de actualización, puedo poner un poco más de lógica. Puedo ver si request dot leave request detail no es igual a null, entonces esta es la ruta que deseo tomar. Puedo ver otra cosa. Y voy a acelerarlo muy explícito con esto más porque no sé si tal vez en el futuro pueda tener algunas otras reglas de negocio. Entonces solo me voy a conformar con estas dos situaciones explícitas donde o
es que el esto debe ser else-si disculpas, de
lo contrario, si de lo contrario si solicita cambio de punto, solicitar aprobación D2 no es igual a nulo, entonces hacer eso, ¿verdad? Y luego las horas extras iban a intentar y rutinario uno regresa. Entonces me voy a llevar todo esto y decir que llevas a cabo esta operación cuando el detalle de las solicitudes de licencia no es igual a nulo. Por lo que eso significa que quien esté consumiendo a quien esté interrumpiendo con este manejador enviando su solicitud necesita asegurarse de que el relleno. Los campos apropiados de acuerdo a lo que quieran. Algunos simplemente mostrando unos sabores diferentes porque podía ir
al RequestHandler peering para cada situación, cada escenario individual, pero entonces se puede hacer un poco a granel juntos, como dije, el manejador. Algunas personas ponen mucha lógica empresarial en esta sección. Entonces, una vez más, eso depende de ti. Entonces si el cambio licencia solicitud aprobación DTO no es igual a nula, tenemos una decisión que tomar. ¿ Qué exactamente vamos a hacer? Sabemos que hemos recuperado y dejamos solicitudes de una forma u otra. No vamos a hacer el mapeo integral que realmente queremos hacer se llama eventualmente los barcos de actualizaciones con otras cosas que suceden. Entonces voy a llamar a espera, dejar solicitudes, repositorio, cambiar estado de aprobación. No. ¿Qué hacemos? Podría darle el DNI. Podría darle el objeto de solicitud de permiso, así
como el estado al que debería cambiarse. Hay una serie de enfoques que podemos tomar. No. Siempre hablamos de repetir código, ¿verdad? Entonces digamos que hago esto, voy a buscar las solicitudes de licencia. Y entonces esto sería relativo al cambio, la solicitud de aprobación detalles ID. Y entonces puedo decir dar a esta operación las solicitudes de licencia que también se recuperó. El valor del campo de detalle para la aprobación, sea aprobado o no. Está bien. No, estoy repitiendo esta llamada para obtener una solicitud de licencia. No, solo puedo hacer esta llamada relativa a si fue la solicitud el TOR cambió solicitudes de
licencia detalle que entró porque si esto se sabe, entonces no puedo obtener esa identificación. Y si esto es nulo, entonces después de tomar una decisión. Entonces, ¿ves todas estas otras cosas? No. De acuerdo, vamos a refactorizar. Entonces para facilitarnos la vida, vamos a volver al mando. Y luego fui a decir, bueno, no, veo buena razón para hasta que el consumidor incluya el DNI. El DNI debe estar presente de cualquier manera, pero sí incluir el DNI aquí. Entonces cuando incluyes el ID ahí, puedo decir fácilmente request dot ID desde fuera del bloque if. Y entonces sé que tengo las solicitudes de licencia que hay que modificar. Ahora bien, si es que todo el detalle GameOver, entonces bien. Sé exactamente qué hacer si es solo la solicitud de cambio. No tengo que ir a encontrarlo específicamente, pero entonces ya lo tengo y solo puedo pasar en el estado de aprobación. Por lo que este método se puede implementar en nuestro Voy a dejar repositorio. Y yo sólo lo voy a hacer vacío. Entonces es sólo esa tarea. Y los parámetros serían DV, request y un booleano. Bueno, tiene que ser booleano nullable de estado de aprobación. De acuerdo, entonces cuando llamamos a eso, sólo
estamos pasando esos dos comandos apropiadamente. Entonces esta es una forma de escribir el código. Seguro que probablemente estás sentado ahí y diciendo, vale, probablemente lo podríamos haber hecho de esta manera o
necesito hacerlo de esta manera para mi situación, está bien. Pero siempre y cuando entienda la flexibilidad que tenemos cuando se trata toda
esa canalización de manejador de solicitudes y cómo podemos manejar diferentes escenarios. Podemos utilizar el manejador de un solo para manejar los diferentes escenarios potenciales basados en la solicitud, en
base a los datos proporcionados en la solicitud. Y, ya sabes, no tienes que tener peering para cada escenario que puedas tener, pero puedes tener un manejador para cubrir múltiples escenarios. De acuerdo, así que ahora que tienes el colgado de ello, quiero que sigas adelante e implemente el delete commons y handlers. Entonces he ido adelante y hecho eso. Y tenemos el comando Eliminar tipo hoja, que está heredando de las solicitudes de IO. Por lo que note no tengo solicito y datatype la última vez que utilizamos las unidades. Entonces este es solo el 0 que no necesariamente tienes que
poner en ese tipo de datos si no se supone que esté devolviendo nada. Por lo que este comando delete tendrá un parámetro para el ID. Y luego dentro del manejador, todo lo que estamos haciendo es recuperar el apropiadamente basado en el ID, y luego lo estamos enviando a la eliminación y luego solo estamos regresando unidad. Y en este punto ese es el tema general para el centro comercial. Entonces es lo mismo para la solicitud de licencia. Sepa si realmente va a exponer funcionalidad para eliminar una solicitud de licencia. Eso depende enteramente de tus reglas de negocio
porque podría ser que no haya borrado duro, solo
es un soft delete o delete realmente significa cancelar, ¿verdad? Por lo que eso simplemente lo señalaría que fue cancelado, desatendido, pero mantener el registro. Entonces solo te estoy mostrando cómo poner en la funcionalidad. Pero entonces una vez más, las reglas de negocio y la aplicación de las mismas son relativas a su situación. Entonces eso es todo para configurar los manejadores de eliminación y actualización para nuestros objetos de dominio. Y más o menos esa es la esencia de todo
el patrón mediador acoplado con el C QR está salpicado. Entonces a medida que avanzamos, lo que vamos a explorar es hacer que esto sea un poco más a prueba de balas porque ¿verdad? Conoce cualquier cosa puede pasar, cualquiera puede venir y crear cualquier cosa, y no hay reglas reales para gobernar lo que es válido versus lo que es inválido. Entonces intentaremos ver ese conjunto que manejamos datos inválidos entrando y cómo podemos hacerlo un poco universal e infalible.
12. Agrega Validación: Muy bien chicos, bienvenidos de nuevo. En esta actividad estaremos configurando la validación para nuestros detalles y nuestros comandos. Ahora antes de seguir adelante, hay unos carros rápidos sobre nosotros que quería hacer
para el código que escribí en el comando de actualización leave requests. Había usado inadvertidamente el detalle de las solicitudes de licencia. Entonces si está en la actualización, entonces debes ser adoptado hoja Solicitar detalle. Entonces si captaste ese error y te lo hiciste a ti mismo, entonces te lo honraste. Si no, entonces puedes seguir adelante y reunirte. Esto me cambia. No hay problema. Ahora de lo que estamos hablando cuando nosotros, en el tema de validación es la capacidad de asegurarnos de que los datos que estamos recibiendo antes de que entre en la base de datos sean bien válidos porque tal como está, hay nada aquí que nos detenga de comprometer, invalidar una base de datos de juguetes. Y una cosa que es muy, muy,
muy importante es la integridad de los datos. Por lo que no quieres crear dos registros con datos vitales faltantes asignación de licencias. No sabemos qué tipo de licencia. Sigue siendo plano en eso, por lo que querrás validarlo y luego rechazarlo por supuesto, si no cumple con los estándares. Ahora, cuando estás acostumbrado a MVC y crees que la validación TBL y estás viendo que en los modelos podríamos fácilmente poner nuestras anotaciones de datos, lo cual es muy cierto. He encontrado que esto es útil. Pero entonces cuando se quiere extender más allá de las predeterminadas, hay
que empezar a construir antiguas extensiones y sal, que es, que también es muy bueno. Pero entonces en este programa en particular, vamos a estar usando validaciones fluidas, que es una biblioteca que nos permite utilizar la sintaxis fluida y billowed muy,
muy poderosas reglas y estructuras de validación son propiedad de nuestras propiedades en nuestro clases. De acuerdo, así que para empezar, vamos a saltar hacia el nuevo Git y supongo que bastante buscado con fluidez. Y ves que aparecen todos estos maravillosos resultados de búsqueda. No hay punto de información. La documentación para esta biblioteca es muy buena y la puedes encontrar en el sitio web para la invalidación dotnet, y verás cómo podemos extender esto y masajearlo y usarlo a toda su capacidad para ayudar con sus necesidades de validación. Entonces voy a seguir adelante e instalar esta biblioteca para las extensiones de inyección de dependencia. Y una vez hecho eso, podemos cerrar NuGet y luego pasar a nuestra configuración. Pero una cosa a tener en cuenta, creo que no lo he mencionado antes. Al hacer clic en esos archivos CSB, en realidad
ves qué paquetes están instalados en su versión. Por lo tanto, alternativamente, si conoces el nombre exacto del paquete y la versión
que deseas, en realidad puedes pegar alineado así dentro de tu compilación de blob de archivos CSV y automáticamente obtendrá ese paquete de NuGet para ti. Entonces esa es una forma que también puedes instalar, resolver estos paquetes en el futuro. Entonces empecemos con nuestros validadores. Saber me preguntaba dónde poner estos validadores, solo
voy a colapsar todo. Para que podamos ver todas nuestras carpetas tipo de comprimidas, ¿de acuerdo? Y entonces por supuesto tenemos los detalles. En los detalles es donde tienen que suceder nuestras validaciones porque son las que se atascan viendo la inflamación en nuestro nombre. No necesitamos validar las que se están utilizando para las consultas. Eso es algo inútil, ¿verdad? Porque las operaciones de lectura no necesitan validaciones. Las operaciones correctas o las operaciones de aumento, sin embargo, sí. Entonces voy a, en una de las carpetas, dejarme empezar con la más fácil. Voy a agregar y nueva carpeta. Y yo sólo lo voy a llamar validadores. Y luego dentro de esto, voy a añadir una nueva clase. Y entonces este va a ser crear hoja tipo D2 validador. Por supuesto, para hacerlo público. Y luego voy a dejar que herede de un validador abstracto. Y luego voy a pasar en nombre de la clase exacta con la que es relativa. Por lo que solo seguiré adelante e incluiré cualquier referencia que falte. Y luego agrega que usando validaciones fluidas biblioteca y luego estamos listos para irnos. Entonces lo que tenemos es un constructor. Entonces CTR tina, tina y conseguimos ese constructor y luego podemos empezar a definir reglas. Entonces déjame solo echar un vistazo rápido al crear hoja tipo D2. ¿ Qué quisiéramos validar en esto? Bueno, querría asegurarse de que los valores de nombre proporcionan derecho. También probablemente podamos limitar el número de caracteres que puede tener esta propiedad de nombre. Ya sabes, la mayoría de ellos no lo sabían, y debe tener una longitud máxima. Y probablemente querría mensajes personalizados para situación para el número predeterminado de días, probablemente
podamos ver que es hostil, ser más, más de uno, debe ser mayor a 0, al
menos para el número predeterminado de días. Por lo que hay una serie de cosas que podríamos validador. Entonces lo que veremos es la regla cuatro. Y luego notarás que este look solo deja las mismas expresiones lambda a las que estamos acostumbrados. Y si no estás bastante acostumbrado a ellos, está bien. Nos acostumbraremos a ellos eventualmente. Entonces es regla para y entonces podemos ver nombre. Y lo genial de la validación de Flint es que puedes encadenar las cosas. Entonces puedes encadenar ya está y decir: Vale, esta regla y esa regla y esa regla y esa regla. Por lo que la regla para el nombre de punto P. Está, digamos, no vacío. Entonces eso significa que debe tener un valor. Y entonces puedo decir con mensaje, así que si viene más de m2, entonces queremos que se imprima este mensaje. Entonces puedo hacer algo así como este nombre de propiedad para que no queramos hablar con. Tipo nombre debe ser su nombre es obligatorio, ¿verdad? Porque entonces estoy haciendo dinámico. Si cambiamos el nombre en la propia clase, entonces podemos olvidarnos de actualizar el mensaje en consecuencia. Por lo que al hacer esto, automáticamente
heredará cualquier nombre o lo que sea que el nombre esté fuera de la propiedad, que realmente lo es también. Correcto. Por lo que diremos que se requiere nombre de la propiedad. Ese es nuestro mensaje de validación. Otra validación que podríamos poner no es nula. Entonces te estamos haciendo saber que esto no debe ser nulo. Y pongo mi punto y coma prematuramente, tan terrible que así tampoco debe ser nulo. Veamos qué podemos tener esos. También podemos decir que la longitud máxima de la propiedad de nombre es tal vez 50. No debe haber tipo de licencia con un nombre que exceda los 50, ¿verdad? Y luego podemos agregar otro con mensaje a eso con el mensaje. Está bien, así que solo te estoy dando ideas. Es decir, puede que tengas diferentes yo soy requisitos para tu validación que yo, pero estos son lineamientos generales que pueden seguir. Entonces veamos el,
el punto por defecto p es. Entonces por defecto es que notarías saber que debido a que el tipo de datos es diferente, algunas de las validaciones podrían no aplicarse necesariamente. Entonces no puedo hablar de longitud máxima con el valor predeterminado es que no tiene nada que ver con un entero, ¿verdad? Ya ves que las flechas se han ido, así que lo estoy viendo debe estar presente, pero luego es entero, así que siempre, más o
menos siempre estará presente, pero podemos dejar eso solo. Pero no debería estar vacío. Entonces nunca puede ser nulo. Realmente intuitivo porque los enteros son valores predeterminados 0 y los valores nulos proporcionados. Pero entonces sí vimos Eso es siempre debe ser mayor que 0. Y entonces estoy seguro de que hay un menos que. Entonces digamos que queremos ver en el sistema no debe haber ningún tipo de hoja que sea Putin que tenga cualquier número de estos Greta que un 100 o hasta un 100. Y debe ser al menos uno. Por lo que los diferentes tipos de datos pueden obtener diferentes reglas y podemos encadenarlos solos según sea necesario. Podemos poner nuestros mensajes en consecuencia para que pueda poner mi mensaje aquí con mensaje aquí. Entonces con esas validaciones en su lugar en la hoja tipo DTO, veamos cómo podemos ir para asegurarnos de que estas validaciones sean nuestras propias. Entonces en el comando que crea el tipo de hoja, correcto, sí
obtenemos esa hoja, esa BTO de nuestro objeto de comando, ¿verdad? Pero lo que voy a hacer antes incluso de hacer el mapeo, porque no quiero desperdiciar recursos en una operación con datos inválidos. Entonces voy a hacer primero la validación. Por lo que voy a decir var validador es igual al validador de tipo New Leaf DTO. Entonces si bien sigue siendo un detalle antes de intentar incluso mapearlo al tipo de dominio, voy a invocar ese validador al que voy a decir resultado de validación
var es igual. Y esperaré a mi validador haciendo la llamada para validar. Y tenemos la opción asíncrona, ahí usar el await. Y luego pasamos en el objeto a validar, que será una solicitud puntos dejan tipo DTO. En este punto, el resultado de validación va a tener o bien flechas no lo son. Entonces voy a ver si el punto de resultados de validación es válido, así que obtenemos que o sea válido o no en base a las reglas. Va a ser válido o no. Si lo es. Digamos si no es válido. Y luego para la legibilidad, quería decir si es válido es igual a falso, ¿verdad? Porque a veces con toda justicia, cuando solo usamos signo de exclamación, a veces cuando estás cansado, emiten incluso te lo pierdes cuando estás revisando el código y así sucesivamente. Entonces solo voy a ser un muy explícito si es válido es equivalente a falso, entonces simplemente voy a lanzar una nueva excepción. Entonces si estás acostumbrado al manejo de excepciones, se lanza la
excepción, eso es todo, básicamente se bloquea. El programa sabrá más adelante veremos un mejor manejo de excepciones
y todo eso en realidad nos puede ayudar a escribir un código un poco más limpio. En lugar de ayudar a un montón de declaraciones if a revisar un montón de cosas, sólo
tenemos excepciones. Ese es nuestro ser a través y estratégicamente ayudar al flujo de la aplicación. Entonces en esta situación, si no es válida, entonces sólo vamos a lanzar una excepción. Vamos a ver cómo podemos hacer excepciones personalizadas también, que se pueden manejar de manera diferente a las excepciones fetales reales. Entonces eso es más o menos. Estamos agregando validación aquí para asegurarnos de que no vaya más allá. No va a ninguna parte cerca de la base de datos. No queremos que se convierta en un objeto de dominio si no es válido. Ahora probemos probablemente la más complicada. Entonces te voy a desafiar a que se conformen validadores para la asignación de licencias, que en realidad no es tan diferente. Solo necesitas asegurarte de que el número de días esté presente en Es más de 0. El ID del tipo de hoja no puede ser nulo, tiene que ser mayor que 0 también. Y entonces podrías ampliarte para asegurarte de que el ID tipo de hoja exista en el sistema. Porque si alguien intenta suplantar y Central Valley tipo ID que no existe en nuestra tabla, entonces esa también es una flecha de validación que
realmente podemos atrapar antes de intentar comprometer la base de datos. Al llegar a la base de datos, podemos hacer eso para el periodo. Entonces te voy a desafiar a que hagas esa, pero vamos a trabajar juntos en las solicitudes de licencia porque ésta va a tener unas cuantas cosas más en ella. Por lo que una vez más, voy a añadir una nueva carpeta validadores, y luego vamos a empezar con las solicitudes de licencia Crea, validación DTO. ¿ Qué necesitamos validar? Bueno, nuestras fechas necesitan ser fechas válidas. Todavía necesitamos obtener la identificación tipo hoja, así que vamos a hacer eso juntos. Y bueno eso es opcional, así que está bien. Entonces vamos a entrar en esa. Por lo que inicia con nuestra clase crea licencias solicita validador de detalle. Yo lo hago público. Y entonces estoy heredando
del validador abstracto relativo a nuestro Crear solicitudes de licencia detalle. Está bien, así que ya escribí parte de la cotización para ti y vamos a pasar por ella. No está terminada porque quiero que hagamos ciertas partes juntas, pero regla para inicio tiene que ser menor que el final. Es ahora vimos que también podríamos usar el valor escalar aquí. Entonces podría haber puesto un entero, pero entonces un entero sería una comparación incompatible con el tiempo. Por lo que podría haber puesto fecha hora, no. Correcto. Tan solo asegúrate de que la fecha de inicio no sea antes de hoy son mayoritariamente antes de hoy, lo cual no es necesariamente el caso, ¿verdad? Por lo que con base en la regla de negocio, es posible que desee comparar en consecuencia, pero esta regla de negocio establece que las fechas de inicio siempre deben ser menores que la fecha de finalización. Y entonces será el mensaje que puedo decir nombre de la propiedad debe ser Antes valor de comparación. Entonces en nuestro detalle de tipo hoja de crear, habíamos codificado duro el 50, codificamos duro el, el uno y el 0 aquí, pero pudimos reemplazarlos fácilmente y hablaba en pársón correctamente. Podríamos reemplazar fácilmente esas áreas con comparación. Dejaré el hardcodificado para nulo, pero solo te estoy mostrando tus opciones, ¿verdad? Entonces estoy viendo que fecha de inicio debe ser antes de NDI lo similitud para la India
lo, debe ser mayor que el inicio ordenado y nombre de propiedad y valor de comparación. ¿ Está bien? No, en relación con el tipo de hoja ID, sí
dije que nuestra validación podría tomar una serie de formas. Uno, quieres asegurarte de que sea mayor a 0, vale, bien. Y todo lo más importante sin embargo, sería que quieres asegurarte de que exista. Ahora si solo comprobamos si existe, aunque enviaran más de 0,
0 nunca existiría como ID de tipo hoja en la base de datos. Entonces podríamos encadenar es a lo largo porque entonces podríamos desperdiciar esa base de datos llamada simplemente haciendo eso. Por lo que podría decir mayor que. Y luego voy a ver 0. Y entonces también voy a ver que debe existir. Entonces estoy usando lo que ustedes llaman delegado aquí, y voy a borrar todo esto y reescribirlo desde cero que puedan ver exactamente lo que van a decir más paréntesis asíncrona, abierto y cerrado, es un ver, por lo que vamos a esperar, pero luego vamos a definir un delegado. Lo sentimos, no somos que estemos usando, le estamos haciendo saber que es un delegado asíncrono el cual toma algunos parámetros. En este caso, necesitamos el ID, que es el valor. Entonces estamos tomando ese valor como parámetro número 1. Y entonces Tolkien es un token de cancelación como herramienta de parámetros. Y luego estoy usando una flecha Lambda para luego definir algún bloque de objetos o bloque de métodos. Por lo que este bloque de método es donde llevaremos a cabo esa comprobación para ver si existe. Ahora probablemente te estés preguntando, vale, eso significa que necesitamos una base de datos llamada ¿cómo exactamente llamo a la base de datos desde solo un validador? El cool de esto es que nos permite inyectar directamente o dependencias. Muy bien, para que podamos continuar inyectando nuestro repositorio para que sepamos inyectar lo pondrá en el constructor. Podemos usar el punto de control para inicializar el campo. Ya cambié a mis guiones bajos, que es opcional por supuesto. Pero usando eso podemos inset de esta función delegada más acing comprobar la existencia del repositorio leaf I. Entonces dos cosas a tener en cuenta aquí son tres cosas. Una, estamos inyectando el validador nos permite
inyectar otras dependencias como nuestros repositorios. Esa es una herramienta. En realidad podemos tener una función personalizada haciendo validación
personalizada para que alguien escriba este IN para ello desde cero. Entonces aquí vemos un punto. La mayoría tendría muselina la asíncrona. Eso está bien. Entonces la mayoría asíncrona. Y luego porque estamos usando asíncrona, tenemos que dejar que el modelo delegado, está borrando. Por lo que el delegado es cuándo tomar dos parámetros. ID que representa el mismo ID que estamos validando o el valor que estamos validando. Y tolkien sería representativo del
token de cancelación que utilizamos son lambda R0 y luego abrir y cerrar llaves. Entonces dentro de estos tirantes rizados tenemos nuestra lógica. Entonces la primera línea de nuestra lógica es revisar o repositorio si existe
el tipo de hoja y luego devolver eso no existe. Está bien, no, esta función que acabo de crear, así que acabo de extender nuestro repositorio genérico para tener un método que devuelva un booleano. Se llama existe y toma int id Así que esto, puedes agregar eso
al repositorio genérico y puedes usarlo en cada uno de ellos. Pero el punto es que podemos saber, usar eso para comprobar si existe algo en una tabla en particular. Y en esta situación, es un bonito zapato para comprobar si existe o elif tipo ID. Por lo que debes saber que estás equipado con agarre para manejar esa hoja tipo ID. Te voy a desafiar para que vayas a configurar validadores para la asignación de licencias. Hit pause, tómate unos momentos, configura los validadores Ford asignación de licencias y cualquier otro detalle que no hayamos visto todavía. Y luego cuando vuelvas un más, solo muéstrale otra forma de que podamos refactorizar nuestro código para especie de reducción en la repetición. De acuerdo, así que espero que realmente tomaras el consejo que te fuiste, trataste de hacerte a ti mismo y que tuviste cierta cantidad de éxito. Eso es bueno. Pero entonces quiero mostrarles sólo otro nivel que podemos hacer esto. Entonces cuando estábamos configurando los detalles, como que
nos dimos cuenta de que estaría terminando repitiendo nuestras propiedades a través de múltiples detalles. Por ejemplo, el crear hoja tipo D2 y el detalle tipo hoja, en realidad
tienen las mismas propiedades bar la fuente. Nadie se basa en el DNI que servimos hasta a través del detalle base. Por lo que las reglas de validación para ambos en realidad serán las mismas excepto quizá la que diga el ID1 al hub de validación para ello. Entonces debido a que uno tiene un ID, uno no, y el validador hasta el momento se han
escrito muy fuertemente porque cuando tenemos el detalle de crear tipo hoja, sólo cuatro para crear detalle tipo hoja y actualizaciones, D2 tendría para tener su propio validador. Entonces lo que he hecho es extenderlo un poco. Y esto es lo que llaman desarrollo impulsado por pin. Significa hacer lo que puedas hasta que ya no sea práctico, entonces refactorías, ¿verdad? Entonces cuando estás aplicando estos principios sólidos, a veces no lo ves justo del bate. Pero entonces en cierto momento te das cuenta de que esto se está poniendo tedioso o esto no es práctico, esto no está en consonancia con el principio. Y así refactoriza tu código para sacar el máximo provecho del principal en ese momento. Entonces en este punto, estamos analizando que estamos teniendo las mismas reglas de validación divididas en múltiples archivos, lo cual está bien. O al menos tener múltiples archivos para validaciones está bien. Pero tener las mismas reglas repetidas puede ser peligroso porque entonces si hay que cambiar la regla en una, podríamos cambiarla en una me falta la otra. Conocemos ese riesgo. Entonces lo que he hecho es tener una interfaz que es una obstrucción de nuestros campos. Está bien, así que como dejar tipo detalle que he creado, dejo ese detalle y esto tiene los campos que sabemos que la hoja tab2 necesita tener. Por lo que en el tipo de hoja DTO, he relacionado heredar. Dejo ese detalle. Por lo que estos dos campos son solo las implementaciones de lo que se ha definido en la interfaz. la misma manera en lift IB2, mientras que sí hereda del detalle base, también hereda del detalle tipo elif. Entonces deja que BTO tendría el ID así como las propiedades que vienen de nuestra interfaz. Ahora. De acuerdo, Entonces, así que el siguiente paso es que podemos crear un validador de detalle de tipo I leave, lo que significa que estoy validando contra la interfaz. Por lo que mis reglas ya no se aplican directamente al tipo de hoja DTO. Podrían ser, eso está bien. Pero entonces como vimos, tenemos que tener múltiplo porque tendríamos que tener una hoja completa tab2 en 14, el Create. Por lo que en cambio puedo configurar validaciones contra la obstrucción. Ambos detalles en realidad heredan de la obstrucción. Por lo que estas reglas se aplicarán a ambos. Y luego cuando tengo que personalizarme, tengo mi hoja, ese validador de detalle en el que digo crear hoja. De detalle validador y todo lo que ya sabemos. Pero luego en el constructor simplemente estoy llamando a un método include. Entonces esto es API fluida es que nos estamos siguiendo para tener validadores que se aplican a otras cosas, se aplican a otra clase. Entonces esto realmente se aplica a la interfaz, lo que estoy viendo cuando estoy haciendo este crear validador de detalle tipo hoja, incluye las reglas del validador de detalle de tipo I leave. Y entonces puedo tener mis métodos de disfraz también. Entonces en el detalle de actualización, podría tener el mismo tipo de sintaxis, pero luego son las actualizaciones, lo que significa que también necesito nuestra regla para. Y entonces puedo decir que necesito una regla para los campos ID. Puedo decir punto p. Y luego ver que me está dando todas las propiedades, incluyendo ID porque está en contra de ese tipo. Entonces mi validación para el ID es que no debe ser nulo y debe venir con un nombre de propiedad de mensaje debe estar presente porque por supuesto, cuando estás actualizando, necesitas enviar el ID del registro que estás actualizando, por lo que sí necesitamos esa regla de validación para la actualización y por eso tendría que tener el archivo separado para la actualización. Pero esto es mucho más limpio porque al menos no tenemos que repetir las reglas para el nombre y el tipo o el nombre. Y el valor predeterminado es, lo siento, no
tenemos que repetir eso a través de ambos por los datos. Entonces verán que realmente lo hizo ya para la solicitud de licencia y para la asignación de hojas, una vez más, para la solicitud de licencia, tengo dejo solicitudes DTO, y es el mismo código que acabamos de ver cuando las solicitudes de licencia detalle datos válidos con inyección. Y en este caso tenemos que inicializarlo y luego hacemos las reglas. Pero cuando miramos en el Creates leave request detail validator, vemos que tenemos que hacer la inyección. Por lo que aún tenemos que hacer nuestra inyección y tenemos que inicializarla. Y luego pasamos esa inyección al método include porque por supuesto, el validador de detalle de solicitud de IO necesita tener esa inyección. Entonces Kant sí lo llama tenemos que proporcionar ese valor para el constructor. Entonces es sólo esa cadena de margarita, pero creo que esto es mucho más limpio de cualquier manera. Y no tenemos que terminar repitiendo todas estas reglas en todos lados. Por lo que notarás que tanto la creación como la actualización se ven muy similares, excepto el hecho de que la actualización tenga esa regla adicional para el ID. Y solo para completar, tenemos los detalles de asignación de ojos. Yo sí tengo los tirones de ID, las interfaces no mostraron eso. Entonces cualquier cosa que sea común en todos, solo
puse eso en la interfaz y luego cualquier otra cosa
se puede poner directamente en el detalle según sea necesario y validado en consecuencia. Pero entonces para crear una actualización, esas son todas las cosas que realmente necesitamos. No tenemos que necesariamente fin de semana sentido de la regla de validación tipo de comentarios de solicitud tal vez limiten la longitud. No necesariamente tenemos que hacer nada por cancelado. Una vez más, solo te estoy dando los lineamientos. Tus reglas y requisitos de negocio pueden ser diferentes, pero configuras tus validaciones según sea necesario. Por lo que nuestra licencia de actualización solicita detalle hereda de la base, y dejo solicitudes detalle. No tenemos que hacer eso para la lista porque no estamos validando la lista. Tampoco estamos validando el detalle de detalle, pero eso crea definitivamente tiene que heredar. Y luego la aprobación de solicitud de cambio que toma de este detalle, pero no estamos del todo en algún momento podemos validar esto. No lo estoy priorizando. Pero luego sobre actualizar y crear, definitivamente
necesitamos tener ya, está bien, no, Para nuestro crear una ubicación, así que dejo asignación y luego ambos crea una actualización heredar de dejo asignación. Por lo que sólo voy a saltar al validador de
asignación que dejo donde tenemos reglas para el número de estos. Entonces ésta es simple y a medida que crece la aplicación cambian las reglas de negocio. Podemos fácilmente poner nuestra validación aquí sin modificar las consultas personalizadas y cualquier otra operación de clientes en torno a dichas reglas de negocio. Por lo que regla por un número de días en este momento sólo tengo debe ser mayor a 0. Y mis mensajes de validación fueron víctimas de alguna copia y pega. Entonces solo estoy viendo el nombre de la propiedad debe ser
mayor que el valor de comparación para el mayor que la regla para el periodo. Entonces el periodo realmente debería ser el año, ¿no? Por lo que para el periodo del año 2020, estos fueron el número de estos que obtuviste. Esos son los puntos polos de la tabla de asignación de hojas en caso de que eso no se explicara antes. Por lo que la regla para un periodo es que debe ser mayor o igual al punto de tiempo 10 puntos año. Y podemos reforzarlo un poco más sobre esto por ahora, solo usaremos eso. Por lo que veremos el nombre de la propiedad del mensaje debe ser después de este año. Y luego todos vimos y escribimos juntos la regla de validación para el tipo de hoja ID y no para el Crear detalle de asignación de dejar datos válidos donde simplemente inyectar el repositorio de troquel de hoja e inicializarlo y pasándolo por encima en nuestro método include. Y para las actualizaciones estaban haciendo lo mismo, excepto que también tenemos esa regla para la identificación. Entonces eso es realmente todo a la validación. Sí, Se tardó un tiempo en llegar. Había algunos reflectores en el camino, pero estoy seguro de que se puede ver cómo se está uniendo todo para especie de reducir una repetición través de múltiples archivos y para un tipo de ayuda también, mantener todo estructurado. Entonces una consecuencia de lo siguiente, los principios sólidos por supuesto, es que vas a terminar con muchos más expedientes que discutimos antes. Pero se está juntando muy bien y ayudándonos a reducir cuántas veces colocamos lo mismo en múltiples lugares.
13. Agrega excepciones y objetos de respuesta personalizadas: Oigan chicos, bienvenidos de nuevo. La última vez que estuvimos aquí, estábamos sentados nuestras validaciones para manejadores y para nuestros diversos detalles. Y en pocas palabras, nos dimos cuenta de que necesitábamos poner algunas reglas para que
cada vez que obtengamos el comando create leaf type con el create leaf type D2 o cualquier detalle. Podemos ejecutarlo contra el validador y luego
devolveríamos una excepción si no es válida. Por lo que deberíamos haber hecho eso a través de todos los manejadores para la actualización y crear cualquier cosa que necesite una validación debe tener al mínimo estas líneas. Por lo que solo voy a dar clic y solo puedes seguir adelante y copiar en caso de que no terminaras eso. Entonces esto es para la actualización. Acabamos de ver el create for the leaf type update totalmente solicita prácticamente todos ellos se parecen a la misma cosa. Muy bien, todos están validando y entrando en una excepción. Ahora, quiero hablar de excepciones personalizadas y respuestas de MRD, ¿verdad? Porque al final del día en este momento, todo lo que estamos haciendo es lanzar una excepción. puede lanzar una excepción en base a que lo lancemos manualmente. También se puede lanzar multi por otra cosa. Podría ser un problema de redirección de base de datos, podría ser otra cosa, ¿verdad? Por lo que siempre es bueno que la aplicación consumidora o lo que sea que esté llamando al manejador tenga una buena idea en cuanto a qué a través de esta excepción. Entonces lo genial de las excepciones es que puedes extenderlas. Entonces el tipo de datos base para una excepción es la excepción que vamos a lanzar aquí lo que vamos a crear el nuestro propio para los fines específicos. Entonces vamos a empezar creando una nueva carpeta en nuestro proyecto. Vamos a llamarlo excepciones. Y en ella vamos a tener excepciones de mala solicitud, no encontrada y excepción de validación. Para que puedas seguir adelante y crear esa carpeta. Y estos tres expedientes, recuérdeme los públicos, claro. Y lo que vamos a hacer es dejar que cada uno de ellos herede de las excepciones de aplicación. Por lo que la excepción es el tipo base de una excepción de aplicación se utiliza como un tipo base para las excepciones definidas de aplicación art. Entonces solo vamos a seguir adelante y dejar que cada una de nuestras clases hereden de esa mantequilla solicitada excepción hará más adelante cuando queramos definir que las peticiones que fueron centrales versus malas, acuerdo, pero por ahora vamos a inicializarlo o leer el código para conectarlo. Por lo que todos ellos tendrán un constructor. Y para este, el constructor va a tomar mensaje de cadena y entonces nuestra base tiene que
heredar el mismo mensaje que se pasa la base siendo nuestra extensión de obligación. Entonces así es como se ve esa excepción. Excepción de aplicación más bien. Perdón por eso. No, seguir adelante. Podemos hacer lo mismo por nuestro teléfono NAACP, pero entonces podemos ser un poco más explícitos con ciertas cosas. Por ejemplo, si vamos a estar viendo no encontrado, probablemente
querremos ver el nombre de lo que se buscaba y quizá el valor clave. Muy bien, Así que estamos pasando en Nombre en el teclado, entonces la base requiere cadena, por lo que tiene tres sobrecargas. Quieres pasar en una cuerda aquí. Por lo que sólo podemos pasar en nuestro mensaje que sabemos que queremos imprimir. Y mi mensaje va a decir que no se encontró el nombre, sea cual sea y su llave. Muy bien, entonces si la búsqueda de algo, no
se forma a través de excepción no encontrada, para la excepción de validación. Nos vamos a poner un poco más de fantasía. Entonces la excepción de validación va a querer R, vamos a querer que devuelva la lista de todas las cosas que estaban mal con la solicitud o los datos que enviarán en su búsqueda, ¿no? Entonces voy a tener una lista de string y lo voy a llamar errores, ¿verdad? Y luego en el constructor, vamos a tener los resultados de validación,
los datos que se están pasando. Por lo que los resultados de validación del resultado de validación vienen de una validación fluida. Entonces solo pasaremos ese objeto entero ahí dentro está usando resultados de validación fluidos. Muy bien, y entonces podemos ver que podemos inicializar o errores. Es decir, sólo inicializa eso aquí. Y luego podemos ver por cada error de validación en los errores. O simplemente puedo acortarlo y decir por cada error en los errores de punto de resultado de validación, queremos agregar ese error. Entonces solo voy a decir urls.py. Y luego solo nos error dot y tenemos un mensaje de error. Ahí vamos. Por lo que ese mensaje de error sería lo que tuviéramos configurado en nuestros validadores como el mensaje a devolver cuando no sea válido. Por lo que ahora tenemos nuestras excepciones personalizadas. Realmente nos vamos a centrar en la excepción de validación, derecho nodal. Y así en nuestros manejadores realmente podemos actualizar esto desde lanzar nueva excepción para lanzar nueva excepción de validación. Entonces si el resultado de validación no es válido, lanzamos esta nueva excepción y pasamos en nuestros resultados de validación y quieres incluir cualquier referencia que falte. Entonces ven aquí es pedir estos libros. Sabemos que lo tenemos definido. En nuestras excepciones de costumbre. Está bien, así que puedes seguir adelante y actualizar cada línea que anteriormente solo
estaba lanzando una nueva excepción para saber lanzar esa excepción de validación. Y por favor recuerda cada vez que estamos incluyendo nuestra excepción personalizada y no la validación de fluidos o la validación de datos sobre arte. Así que adelante y actualízalos todos y asegúrate de que estás incluyendo la biblioteca del carrito. Ahora en este punto, me imagino que te estás preguntando, Vale, Entonces, ¿cómo puedo usar las otras excepciones? Bueno, veamos la excepción no encontrada. Entonces en C, la operación de borrar, tenemos que encontrar el registro, luego hacer la eliminación y luego regresar bien, las unidades, correcto, pero entonces ¿y si no encontramos ese registro? Bueno, entonces esa es una oportunidad perfecta donde decimos si el objeto que buscamos devuelve nulo, o si la operación devuelve nulo, entonces lanzamos la excepción no encontrada. ¿ Y qué pasaríamos a la excepción no encontrada? Recuerda que eso es que se necesitan dos parámetros. Se toma el nombre y la clave, por lo que fácilmente podríamos decir nombre fuera. Y entonces esta es una buena manera de mantenerla fuertemente tipada. Por lo que estamos buscando un tipo de hoja. Por lo que el nombre fuera de los tipos de hojas o decir en el tipo de hoja con el id que pasó en no era teléfono u otras solicitudes. Dot ID, correcto. Ahí vamos. Muy bien, entonces puedes empezar a decorar tus manejadores de Eliminar con esa sola línea. Entonces en el caso de las solicitudes de licencia, eso será lo mismo excepto que estamos comprobando si la solicitud de licencia es nula, y entonces esta sería una solicitud de licencia no telefónica. Adelante y actualízate. Por lo que puedes hacer eso con asignación de licencias también. Muy bien, así que una vez que hayas terminado con eso, entonces has resuelto algún buen
manejo de excepciones al menos o manejo personalizado de excepciones en tu mano sin mano. Ahora otra cosa que queríamos mirar son las respuestas de los clientes. Entonces, ¿qué pasa cuando hay un resultado positivo? Y aun cuando haya resultados negativos, ¿verdad? Entonces aquí es donde tu, tus necesidades arquitectónicas pueden diferir de las mías en cuanto a lo que quieres hacer. Pero aquí hay un concepto. Podemos definir tipos de respuesta personalizados o tener respuestas base donde podamos devolver datos basados en la situación. Entonces si falla, podríamos arrojar la excepción segura. O podríamos tener una respuesta del cliente que tenga una bandera falsa de éxito, contiene los errores de validación. Y así el cliente siempre sabrá que estoy esperando una respuesta de este tipo de datos que siempre deberíamos tener estos datos. Si la bandera es falsa, que conozco campo IT, si es cierto que sé que pasa. Entonces vamos a ver algo así. Entonces una especie de alternativa a simplemente lanzar una excepción o devolver solo el ID, lo que podríamos hacer es definir una nueva carpeta. Por lo que tenemos una nueva carpeta aquí llamada respuestas e inits tenemos una respuesta de comando basada en archivos. Y tendrá tres propiedades. Éxito, que es un mensaje booleano, que es una cadena, y una lista de errores, caso de que necesitemos enviar de vuelta los errores, correcto, entonces después de tener esta respuesta de comando base, podemos extenderla para facilitar el operaciones específicas. Entonces por ejemplo, un resultado probablemente querrá extender esto es que queremos devolver certeza
a cada vez que se crea o actualiza un tipo de hoja, ¿verdad? Por lo que la respuesta base podría no ser suficiente. Por lo que podemos crear una respuesta personalizada asociada a los tipos de hojas. Por lo que ya tenemos esas solicitudes web. Entonces podrías crear otra carpeta llamada respuestas, y luego podríamos extender eso. No me voy a complicar tanto. No obstante, lo que haré es solo agregar otra propiedad aquí y lo llamaré ID, ¿verdad? O podemos llamarlo registro de identificación. Entonces eso significa que cada vez que pasa algo, creamos, en lugar de simplemente devolver el id, lo que yo podría hacer es, y esto es un cambio enorme. Entonces pasemos por ella línea por línea y me dirijo a las líneas rojas a medida que lleguemos. Entonces inicialmente estábamos diciendo que me consigan los resultados de validación, arroje una excepción, de lo contrario continúe y luego devuelva la palanca. Vete. En este caso, deje solicitud de identificación. ¿ Está bien? Saber lo que estoy haciendo es que estoy viendo en primer lugar, inicializar la respuesta, así que tenemos una respuesta base, eso está bien. Entonces estoy viendo si el resultado de la validación es falso, establece esos engendros pensados éxito a caídas. El mensaje que puedes poner en un mensaje personalizado si lo deseas. Y luego los errores que quisiéramos llenar con los mismos errores de validación. Por lo que sólo estoy seleccionándolos de la lista de errores son de esta colección de errores. Por lo que este selecto tiene una línea roja porque necesito una biblioteca extra, que es System.out links. Entonces, solo asegúrate de que pudiéramos ver eso juntos. Y luego solo consigue los mensajes de error, los
pone en una lista, y luego eso entra. Entonces eso es un lindo uno liner en sí el para cada bucle ¿verdad? Entonces conocido más tarde, vemos si el anuncio fue exitoso y soul, lo que sucede es que si esto se siente poco excepcional habría
pasado por un automáticamente por Entity Framework de todos modos. Entonces si esto no sucede, entonces obtenemos una excepción. Por lo que nunca llegaría tan lejos si esto no fuera exitoso. Entonces el éxito es cierto. Nuestra respuesta es la creación exitosa, y luego configuramos el ID. Entonces eso es lo que te veré en eso a través del tablero, solo
estamos devolviendo identificaciones, ¿verdad? Sólo estábamos devolviendo el DNI para el registro recién creado. Podrías tener un requisito donde necesites devolver todo el registro. En ese punto, podrías simplemente extender la respuesta del comando base crea una nueva clase llamada crea una respuesta de solicitud de permiso. Y que no dolía de esto y darle el parámetro DTO para una solicitud de licencia DTO, haces tu mapeo, lo devuelves. Como dije, no me voy a complicar tanto, ¿verdad? No, no podemos mirar eso en nuestra lección de consideraciones futuras o consideraciones adicionales, pero solo quería conseguir este concepto de una respuesta del cliente a través. Entonces regresamos la respuesta. Ahora esto tiene nuestra línea roja porque habíamos definido nuestro comando para volver int. De acuerdo, para que podamos pasar a nuestro mando. Hazle saber que solicito se supone que devuelva la respuesta de comando bestia. Está bien, y entonces aparecerá nuestro error y saltamos buck y estábamos bucking o handler, vemos que
podemos devolver respuesta tan pronto como también actualicemos el manejador, ¿verdad? Entonces recuerda que tenemos ese comando y tipo de retorno peer-to-peer. Entonces déjame solo actualizar eso. Y luego finalmente el tipo en la tarea para el mango. De acuerdo, Así que ahí, entonces cuando quieras cambiar,
altera tus divs de retorno, eso es todo lo que tienes para hacer todos esos cambios una vez más, ¿verdad? No hay respuesta de comando bs. Entonces si quieres ponerte granular, sigo diciendo que no tienes que conseguir como libro granular basado en tus requisitos, necesitarás ser que quizá no necesites. No lo estoy haciendo un requisito para oro y crear respuestas de comando para cada manejador solitario o manejador de comandos que tengo. Ahora mismo, sólo voy a estar usando la respuesta base. Y también voy a estar haciendo ese cambio a la solicitud de licencia por
ahora al menos para que llegues a ver la idea de cómo puedes tener excepciones personalizadas y, o cómo puedes mejorar en esa parte superior de tus respuestas personalizadas.
14. Refactoring y consideraciones adicionales: Oigan chicos, bienvenidos de nuevo. Esto es más una sesión de revisión que una sesión de codificación y sólo algunas consideraciones adicionales. Por lo que las gargantas o actividades pueden haber mencionado que tienes alternativas y siempre tienes alternativas. Ya sea que estas alternativas sean buenas o malas o comillas, la
mejor práctica a veces es relativa a lo que estás haciendo y a lo que necesitas lograr. Dicho eso, por supuesto, hay principios fundacionales a los que se quiere adherir
independientemente y a los que tendrán esos como su guía, entonces es más que probable que vaya a tomar mejores decisiones. Entonces una cosa que queremos ver es la separación de preocupaciones, ¿verdad? Por lo que la separación de preocupaciones nos llevó a tener múltiples proyectos y mucho más archivos de los que probablemente teníamos en otros proyectos ya que soy un hecho ensemble, creo que ya tenemos más archivos en este proyecto que en toda la aplicación que ambos estamos para reconstruir, ¿verdad? Entonces solo en este proyecto, tuvimos múltiples DTL. ¿ Por qué teníamos múltiples detalles? Bueno, uno queríamos ese tipo de separación porque podría haber reglas de
negocio que rijan lo que puede ocurrir en cualquier tipo de operación. Por lo que echemos un vistazo a mis solicitudes de detalles. Deja solicitudes detalles. Teníamos uno para el listado el cual sólo tenía los datos que era absolutamente necesario para cuando necesitamos atender la lista de solicitudes de licencia. Tenemos un DTO que tiene todos los campos que coinciden con lo que hay en la tabla. Y esto podría verse como el detallado DTO. También teníamos la actualización, que sólo tenía unos pocos campos requeridos para una operación de actualización. Teníamos los Crea donde teníamos pocos campos para una operación de creación, etcétera. Por lo que los dividimos en múltiples archivos. Entonces esa es una de las que quería decir consecuencias de apegarse a esos principios de separación de preocupaciones. Pero vas a terminar con mucho más borroso de lo que probablemente estás acostumbrado. Y vas a tener que separarlos de una manera que siempre los puedas encontrar. Entonces empecé con detalles luego en detalles, los
separé por el tipo. Y luego después de eso entonces empiezas a ver los archivos también configurará los validadores. Y luego por las diferentes reglas de validación que podrían requerirse para los diferentes DTU, tenemos múltiples validados, un suelo uno para Crear, tenemos 14 actualización. Pero entonces al mismo tiempo vimos donde necesitábamos un tipo de consolidación porque era algo imponente y empezamos a repetirnos. Por lo que tienes el principio DRY. Por el principio
DRY, lo que hicimos fue crear una interfaz que tenía los campos base. Entonces permítanme ver tal vez la asignación de licencias será un mejor ejemplo de eso. Entonces tenemos, dejaré asignación, que tiene todos los campos que son necesarios para la asignación de vacaciones anuales. Entonces tenemos nuestros detalles heredando de esta interfaz, ¿no? Entonces sí, ves de nuevo la implementación o ves los campos aquí arriba. Y de nuevo, lo que realmente están siendo impulsados por este requisito de la herencia desde la interfaz. Y entonces podríamos configurar un validador contra la interfaz. Por lo que se están validando todos los campos comunes, derecha, asentados por la interfaz. Y luego los otros validadores solo están incluyendo las validaciones y luego implementando sus validaciones personalizadas según sea necesario. Eso nos ayuda a reducir la repetición del código. Y una vez más, a medida que tu proyecto crece, corres el riesgo de
olvidarte de actualizar una parte de tu proyecto cuando haces un cambio en alguna parte. Conoce otra cosa a tener en cuenta en nuestro validador, inicialmente, las inicializaciones en nuestros manejadores, y no creo que lo señalara antes, alguien para asegurarme de que sí sé es que cuando estamos inicializando estos validadores, y no creo que lo señalara antes,
alguien para asegurarme de que sí sé es que cuando estamos inicializando estos validadores,
tienen que pasar en un objeto del tipo que está esperando, ¿verdad? Porque recuerda que este validador necesita el repositorio tipo I leave y luego tenemos al constructor viendo necesito el repositorio tipo elif. Por lo que no hay forma de instanciar esto sin pasarlo. A mí me gusta que lo hemos hecho aquí. Entonces si tuvieras línea dirigida y todo este tiempo, pido disculpas, pasé por alto esa, pero puedes seguir adelante y hacer eso porque lo que necesitas hacer se inyecta en el manejador y luego haberla
inyectado en el a 100 y solo lo pasas de manera similar a cómo, cuando lo necesitamos para incluir al validador base, tuvimos que hacer lo mismo. Muy bien, este es el mismo principio, inyección de dependencia. Está bien, así que espero que eso haya aclarado un error y si no tuviste ese error, entonces te felicito. Ahora otra cosa que descuidamos y podemos abordar saber es la inclusión de todos los detalles que se requieren para que cualquier operación de mapeo sea exitosa. En este momento sólo tenemos mappings para el like, para like request el azulado a la lista son estos son los únicos el dominio al detalle. Entonces por supuesto que necesitaremos, una vez que estemos haciendo mapeo, como en este manejador, estamos mapeando desde el detalle de asignación de dejan para dejar asignaciones. Por lo que eso significa que tenemos que tener representación de la misma dentro de nuestro perfil cartográfico. Aquí he agregado las asignaciones adicionales, todas aquellas para solicitudes de licencia que me gusta
agruparlas para que no se mezclen por todo el lugar. Y toda la idea de agrupar es una lata probablemente solo crear nuestra razón, nuestra propia las secciones para que sepas exactamente dónde están, qué inicio conjunto o pueblo puedes llamar a tal aplicación crece. Quizás quieras hacer algo así. De acuerdo, entonces eso es otra cosa que definitivamente necesitamos abordar antes de seguir adelante. Una de las cosas de las que quiero hablar 0 estrellas es nuestra estructura de carpetas. Por lo que había mencionado varias veces que su estructura de carpetas puede diferir en función de su temperamento o de su Outlook o de su visual. Y cuatro sostienen estos expedientes necesitan ser arreglados, ¿verdad? Por lo que me gusta pensar en ver QRS o la implementación del caballito de mar, nuestros propios escenarios. Y luego todos los escenarios, tenemos activos particulares que se requieren. Entonces cuando digo es un escenario, quiero decir, crear una asignación de licencia, ese es un escenario lo que se requiere para crear y evaluar? Necesitas tu manejador de comandos. También necesitarás tu objeto de comando y quizá necesites algunos otros detalles. Por lo que es posible que desee crear y simplemente incluir, es posible que desee crear una carpeta dentro de asignaciones de licencia que tenga tal vez en lugar de características que habría creado asignación de licencias. Y luego tienes tus manejadores y todos tus activos dentro de esa carpeta. Por lo que la estructura de carpetas puede diferir siempre la organización sea tal que puedas encontrar tus activos cuando los necesites, entonces estás en el camino correcto. Ahora mientras estoy en el comando Crea dejar asignación, otra cosa que podrías considerar, por lo que ves que hay tantas consideraciones, esto no está puesto en piedra, ¿verdad? Otra cosa que podrías considerar otra es que dentro del comando, es un patrón conocido simplemente usar el objeto de comando para que tus campos lleven a cabo los comandos. En lugar de tener un DTO completo dentro del comando, en realidad podría poner los campos desde el detalle dentro del comando. Y luego simplemente validas el comando en sí, la solicitud en sí, el objeto que entra en el manejador sería simplemente este objeto. No tendrías que decir request dot, leave allocation, dto dot este campo, solo
dices request dot este campo, ese campo, etc Así que hay una serie de opciones disponibles para ti, pero me voy a apegar a la detalles con todo lo dicho y hecho a modo de conclusión, el núcleo o el proyecto de aplicación tal como lo tenemos, contiene la funcionalidad central de la aplicación. Entonces ves que todo es abstracto en este punto. Vamos a pasar al siguiente módulo donde empezamos a poner algunas cotizaciones reales, carne en los repositorios y cualquier otra lógica que sea aplicable. Miramos cómo funciona el patrón mediador que promueve el acoplamiento suelto acoplado al patrón C QRS donde podemos saber exactamente qué archivo está haciendo qué. Y este manejador va a manejar este comportamiento, este escenario. Y podemos esperar esta respuesta en particular por ese tipo de relación o comportamiento que hemos implementado. También miramos el diseño basado en características, que en mi opinión te ayuda a ver que, de acuerdo, la característica relacionada con los tipos de licencia, puedes encontrar todo dentro de eso. Y eso para mí eso ayuda con el diseño. Puede que tengas otras ideas, pero esta es mi recomendación. Y luego miramos la validación usando Fluent API o una validación fluida. Muy bien, así que esas son las cosas que hemos mirado en este módulo. Entonces, cuando volvamos, definitivamente le pondremos un engranaje y empezaremos a poner algo más de funcionalidad.
15. Descripción de la sección: Oigan chicos, bienvenidos de nuevo. En esta lección, vamos a iniciar nuestro módulo donde configuramos nuestra capa de infraestructura que probablemente te estés preguntando,
vale, ¿cuál es la capa de infraestructura? Bueno, uno, se va a sentar dentro de esta carpeta llamada infraestructura. Y dos, es el proyecto en el que realmente vamos a implementar todas nuestras obstrucciones que se definieron en la sección central. Por lo que estaremos configurando nuestros contextos de base de datos que estaremos utilizando Entity Framework Core como nuestro ORM para comunicarnos con nuestra base de datos bajo nuestra aplicación. Pero en esta capa, configuras todo está asentado. El registro tú, vamos a implementar los repositorios que vamos
a poner en la carne real, la aplicación. Entonces empecemos. Entonces vamos a crear dos nuevas bibliotecas de clase. Uno llamado HR dot DV infraestructura de gestión y otro llamado HR dot leave management persistencia pensamiento. Conocer el proyecto de persistencia o capa de persistencia, se ocupará de nuestra comunicación con nuestra base de datos. Entonces aquí es donde nuestro contexto de base de datos o bibliotecas y referencias EF Core, todo eso. ¿ Fue ahí en lugar de infraestructura, ahí es donde se sentarán nuestras implementaciones. Muy bien, entonces entre estos dos estará implementando el repositorio. Estaremos configurando cualquier otra implementación de terceros que se necesite. Y también configuraremos servicios para ser bootstrapped en los servicios lo llaman colegas de servicios de IA Sean o el contenedor de inyección de dependencia para ASP.Net Core. Recuerda que hay que hacer las bibliotecas. Está trueno. 2.1. Y ya pasaste por crear todo el colapso de la diversidad puede seguir los mismos pasos. Y cuando volvamos, empezaremos con configurarnos en diferente núcleo de trabajo en o capa de persistencia.
16. Agregar núcleo de el marco de la entidad: Muy bien, entonces estamos de vuelta y vamos a estar montando nuestros proyectos de persistencia. Entonces empecemos agregando una referencia a nuestros proyectos de aplicación. Por lo que tenemos el proyecto de dominio que tiene todas las entidades. Y proyecto de aplicación final tiene una referencia al proyecto de dominio. Por lo que nuestro proyecto de persistencia va a tener una referencia a nuestro proyecto de aplicación comienza por lo que podemos simplemente hacer clic en aplicación para igualar k. Y entonces esa es una dependencia. No también vamos a ir a paquetes NuGet. Vamos a buscar Entity Framework, pero el que vamos a estar recibiendo es entity Framework, Core dot SQL Server. Entonces éste cuando se baje, vendrá con todas las dependencias que necesitamos. Por lo que solo podemos seguir adelante e instalar la última versión estable. Y aún en ti obtienes, solo
vamos a seguir adelante y buscar extensiones de configuración e instalar Microsoft dot extension no options dot configuration extension. Entonces esto será útil cuando vamos a estar sentados en algunas de nuestras cosas. Entonces después de que hayamos hecho todo eso, podemos seguir adelante y crear una nueva clase. Y yo llamé a la mía la edad, nuestros contextos BB de gestión de plomo. Entonces crea esa nueva clase. Puedes llamarlo otra cosa. Probablemente puedas simplemente llamarlo gestión de dejar, contextos
EB o contextos DVI, eso está bien. Pero estará heredando de contextos BB ahora contextos DVI comenta a nosotros cortesía de microsoft dot Entity Framework Core. Para que podamos seguir adelante y hacer esa referencia. Y entonces podemos hacer que nuestro contexto DB sea consciente de las diferentes entidades que habíamos definido. Entonces si estás familiarizado con EF Core, entonces sabes exactamente a lo que me refiero. Entonces en este expediente tenemos algunas cosas. Tenemos un constructor donde inicializamos nuestro contexto DB para tener un parámetro de contextos DVI, opciones fuera de su propio tipo, y el nombre es Options, y pasamos eso a la base, que es contextos DVI . Entonces tenemos nuestra DB se sienta en relación a nuestras diferentes entidades. Por lo que sólo puedo seguir adelante e incluir las referencias faltantes para esos y todo debe ser todo verde. A continuación, vamos a anular algunos métodos. Entonces el primero que estamos anulando sería el on model create team. En realidad es más rápido simplemente empezar a escribir sobre él y luego presionas Espacio y luego verás todas las opciones. Por lo que estamos anulando el sobre creación de modelos. Entonces este método se ejecuta cada vez que se está generando la base de datos, ¿verdad? Para que podamos sentar ciertas reglas. Entonces la regla que vamos a configurar aquí con seguridad, al menos, ¿verdad? No. Si quisiéramos ver la base de datos, podemos hacerlo desde aquí, pero no estamos listos para sembrar ya que al menos aún no. Queremos aplicar configuraciones desde el montaje. Y luego vamos a decir tipo de gestión DV, contexto DV. Y voy a decir montaje de puntos. ¿ Está bien? Entonces eso es todo lo que estamos poniendo en nuestro modelo creando al menos, ¿verdad? No. Como dije, si quisiéramos sembrar la base de datos con configuraciones espaciales para tablas, entonces siempre podríamos dentro de este método para que se apliquen siempre que se genere en el modelo de base de datos. Muy bien, otra cosa aunque que queremos anular la costa es nuestra Guardar Cambios. Alguien para elegir guardar los cambios con la cancelación Tolkien como su parámetro. Y voy a equipar este guardar cambios con algún código hermoso, algún código muy práctico que nos va a permitir hacer algunos registros de auditoría automáticamente. Entonces recuerda que habíamos configurado una entidad base para cada uno de estos que venía automáticamente con como un usuario creado, son creados por u otro, crea un dato, etcétera. Por lo que voy a establecer el bucle foreach para pasar por cada entrada en las entradas de punto de estructura de cambio. Y solo estamos haciendo una entidad de dominio basada en costos de datos implícitos. Y solo puedo seguir adelante e incluir la declaración de uso para ello. Y luego para cada uno, lo que quiero hacer es fijar la fecha, añadida, fecha, modificada en todo momento. Por lo que siempre puedo ver una vez que estás a punto de ver algún cambio, quiero entidad de punto de entrada, cristal de
punto modificado por nuestros datos Last Modified, más bien, estamos lidiando con la fecha, ¿no? No. Tiempo. No. Correcto. Y luego fui a hacer un cheque y solo diré si el estado de entrada es equivalente a entidades, agregó
State DOT, lo que significa que se están agregando beats, es un nuevo récord. Entonces quisiéramos sentar el creado lo a datetime dot null. Por lo que permitimos es nuestra fecha creada más bien, por lo que siempre estableceremos el Último Modificado. Quiere que se cambien algunas cosas. Un voltaje que estamos sentados lo modificó. Pero entonces sólo cuando se está agregando a, establecemos el lo creado y así es. El código básico más básico para implementar la auditoría que puede encontrar alguna vez. Una vez más, esto es automatizado, por lo que cada vez que golpeamos Guardar cambios, hace todo esto. Y entonces solo causó la base c de g y g es método en el fondo. Entonces eso es todo por agregar al marco a nuestra capa de persistencia. Cuando regresemos, comenzaremos a trabajar en algunas implementaciones.
17. Implementar la capa de persistencia: Bienvenidos de vuelta chicos. En esta lección vamos a estar implementando nuestra capa de persistencia. Entonces cuando hablo de implementar la capa de persistencia me estoy refiriendo específicamente a nuestro repositorio genérico, ¿verdad? Entonces sólo tenemos la abstracción, pero no tenemos código para respaldar esto. Entonces sigamos adelante y hagamos eso. Por lo que agregamos una nueva carpeta. Y voy a llamar a esta carpeta repositorios. Y luego en esta carpeta vamos a agregar una clase que representará la implementación
del repositorio genérico relativo al tipo T. Cells degeneran en la clase. Nosotros como de costumbre lo hacemos público, y luego lo hacemos relativo a t0. Y luego hereda del repositorio genérico IJ, que también es relativo a T donde clase de colon T. Muy bien, adelante e incluye cualquier referencia que falte para luego permitirle implementar la interfaz. Entonces seguiré adelante y escribiré la cotización y luego lo pasaremos juntos. Ahora antes de continuar, me di cuenta de que me superé a Zillow, Suiza por copiar y pegar teléfono. Estamos sentados en la interfaz. Entonces así como algunas caricaturas para la actualización y la eliminación, podemos quitar la T, ¿verdad? No hablamos para devolver nada cuando hacemos una actualización o eliminamos. Por lo que esas dos solo deben ser tareas, para que puedas seguir adelante y hacer ese cambio. Y entonces eso por supuesto, afectará nuestra implementación. Por lo que nuestro repositorio genérico comienza con un constructor que está aceptando un parámetro de tipo leave management contextos DVI. Por supuesto, el contexto DB es básicamente nuestra conexión a la base de datos. Por lo que sí lo necesitamos en nuestro repositorio para poder llevar a cabo nuestras operaciones o agregar método. Se inicia con nuestra ponderación una llamada de contextos DB para agregar un sumidero donde acaba de pasar en la entidad EF Core es lo suficientemente
inteligente como para inferir qué entidad se está pasando en relación con todos los conjuntos de DB que se han definido en nuestro contexto DV. Y por db sit me refiero a estos. Entonces, sea cual sea el tipo de datos
que se pase, sabrá si es uno de los conjuntos de DB Eso es lo que reconoce. Por lo que sólo vamos a seguir adelante y agregar la entidad, guardar los cambios en el nuevo retorno, esa entidad. Para el Delete, una vez más, elimine el parámetro de tipo de la tarea. Pero todo lo que va a hacer es mirar y contexto DB, encontrar el conjunto relativo a t0 que se está dando y va a quitar esa entidad de ese asiento. Muy bien, y luego después de eso guarda los cambios. Por lo que notarás que realmente no pasa nada hasta que veas si cambia. Este es ese compromiso final con la base de datos. Tenemos el método existe donde obtenemos una identificación para nuestro registro. Y lo que haré es buscar la entidad usando el método GET local, que veremos en unos cuantos. Y luego regresamos que no es igual a nulo. Entonces cuando no es igual a nulo, entonces sí, existe de lo contrario eso es falso. Por supuesto, en el gueto, lo que estamos haciendo es devolver una llamada sin ponderar a DB context dot set t Así que una vez más, estamos buscando en conjunto específico y estamos encontrando el registro relativo a la ID. Está bien, para nuestra leí en la lista t, que es consigue todo eso es lo que está regresando. Todo lo que estamos haciendo es buscar en el set y estamos haciendo una lista de dos asíncrona en ese set. Entonces solo estamos sacando todo de ese set y enviándolo a lista y devolviendo eso en nuestra guitarra para las actualizaciones, lo que estamos haciendo es establecer la entrada al estado para modificarlo para que el EF Core, empezaremos a rastrearlo y luego seguimos adelante y guardamos los cambios. Entonces eso es más o menos para nuestra implementación para el repositorio genérico. Muy bien, entonces ahora que tenemos implementado nuestro repositorio genérico, ahora
necesitamos implementar nuestros repositorios específicos para que podamos seguir adelante y sumar esos. Entonces, empezando por el repositorio tipo hoja, vamos a ver cómo se ve la implementación. Por lo que he creado el repositorio tipo hoja. Se trata de una clase pública llamada repositorio tipo hoja, heredando de la implementación del repositorio genérico relativo al tipo de hoja. Está bien, y luego vamos adelante y decimos que también
es para heredar del repositorio tipo elif. Por lo que las líneas rojas aquí indican algunas cosas. Uno, necesitamos traer el espacio de nombres faltante a, necesitamos poner en la implementación real esto,
este cisne, correcto, esta interfaz no tenía ningún método adicional, por lo que está bien para null. Y entonces esto se está quejando porque necesitamos tener presente el contexto DB. Para el repositorio genérico. Entonces recuerda que cuando estás heredando algo que tiene una dependencia, tienes que poner esa dependencia en el heredero también. Entonces esa es una solución sencilla. Simplemente obtenemos el constructor y luego hacemos nuestra inyección de dependencia. Y eso es para el contexto DB, por supuesto, pero entonces también necesitamos dejar que el bajo note que
también puede usar este contexto DB que se está inyectando. Y eso es todo para el repositorio tipo hoja. Por lo que el contrato no tenía ningún método adicional. No hay nada extra que implementar. Y porque está heredando del repositorio genérico con relación al tipo de hoja. Al usar esta implementación, tenemos acceso a todos los métodos que aquí se definieron. Ahora veamos algunas más complicadas. Entonces echemos un vistazo a las solicitudes de licencia. Deja peticiones repositorio sin esto parecen requisitos de dependencia. Por lo que tenemos que asegurarnos de que inyectamos el contexto DB posible a las abejas. Adelante e incluye cualquier espacio de nombres que falte, y luego tenemos que implementar la interfaz. Por lo que esta interfaz en realidad tenía algunos métodos, extra. Teníamos estado de aprobación de cambios, teníamos solicitudes de licencia de obtener con detalles, y agregamos otra para obtener solicitudes de licencia con detalles por ID. Pocas cosas están sucediendo en esta en particular. Por lo que las implementaciones aquí serán diferentes a las genéricas porque éstas son específicas de algunas solicitudes de licencia relacionadas con operaciones. Por lo que las implementaciones son las siguientes. Para la solicitud de aprobación de cambio, estamos obteniendo un parámetro de solicitudes de licencia y estado de aprobación. Estamos ajustando el estado aprobado de la búsqueda de palanca a cualquier valor que vino y el parámetro. Y luego estamos configurando contextos db no solicitudes de permiso de entrada. Entonces ves que esta vez no es una entidad, no es genérico. Es muy específico porque estamos en este repositorio específico. Entonces estamos configurando el estado de entrada o el estado de la entidad, modificarlo para esa solicitud de licencia, y luego guardamos los cambios para que empiece a rastrearlo y luego ver si el cambio en consecuencia. Ahora ves que se trata de una operación muy específica a diferencia la actualización general donde no podemos dar cuenta de lo que se está cambiando. Por lo que acabamos de poner todo para modificarlo y permitirle que el camión. Una vez más, estas son solo ideas porque tal vez tus reglas de negocio sean mucho más complicadas o la operación que tienes que llevar a cabo dentro
del repositorio es mucho más complicada que solo sentarte un campo. Por lo que puede necesitar una función especializada para eso. Ahora para las solicitudes de licencia del get's con método de detalles, todo lo que realmente estamos haciendo es consultar la tabla de solicitudes de licencia. Por lo que var solicitudes de licencia es igual a esperar contextos DVI no dejar solicitudes. Y luego estamos incluyendo el tipo de hoja. Por lo que no necesariamente siempre queremos incluir el tipo de hoja. No sabemos bajo qué circunstancias podemos necesitarlo. Entonces tenemos éste relativo a los detalles que se necesitan junto al registro para el genérico regular que no está incluyendo es solo devolver datos de la tabla. Por lo que esta vez estamos incluyendo detalles. Podría ser este tipo de hoja, podría ser más tantos incluye Como pueda necesitar. Y luego los estamos empujando a todos a listas. Y luego estamos regresando para la final donde sólo estamos recibiendo una solicitud de licencia con detalles basados en la identificación. Estamos haciendo algo similar, excepto que estamos haciendo el include y luego dx en el primero o predeterminado fueron el ID de cola coincide con el ID Boston. Ahora estamos haciendo primero nuestro defecto aquí en contraposición al hallazgo, un fregadero que hicimos en el repositorio genérico por cómo funcionan estos métodos, no se
puede hacer una inclusión cuando se hace un hallazgo, simplemente no funciona. Entonces cuando tienes que hacer un include, tienes que usar el primero o el sencillo o predeterminado, cualquiera que sea con el que te sientas más cómodo. Y luego regresamos la solicitud de licencia que se ha encontrado. Por lo que podemos saltar para dejar asignación y vemos que es una implementación relativamente similar. Contamos con métodos similares. Entonces puse estos métodos aquí solo para
señalar que puedes tener métodos personalizados en estos repositorios. Es posible que no necesariamente los necesite en su aplicación, úselos como los necesite. También retengo esa línea roja porque en caso de que te estés metiendo en todo lo que necesitas es incluir esa referencia, ese EF Core y entonces eso es bueno. Muy bien, entonces nos queda una actividad importante y luego terminamos con la capa de persistencia. Y eso es armar la clase de registro para la persistencia. Por lo que sólo servicios de aplicación local, distribución Hadar. Definitivamente la persistencia necesitará uno. Así que adelante y agrega esta nueva clase. Estoy llamando a servicios persistentes o distribución. Debería ser una clase estática pública. Y luego en ella tendremos. Un método que devuelve sirvo como colección y lo estamos llamando configurar servicios persistentes. Entonces por supuesto, como de costumbre, adelante e instalar cualquiera o cualquiera de las declaraciones usando que se necesiten. Y luego dentro de este método, lo que vamos a hacer es escribir código para vagar. Almacena contexto DB, y agrega nuestra herramienta de repositorios, la colección de servicios. Y este es ese método completo de, por supuesto, lo que las líneas rojas porque siempre me encanta mostrarte lo que Redlands me
a existe y cómo puedes resolverlos. Pero así es como debe verse este método. Por lo que puedes seguir adelante y empezar a incluir en las declaraciones de uso que faltan. Entonces, en primer lugar, tenemos el contexto services.js ADB donde pasamos en el tipo que es los contextos db dejan contexto de base de datos de administración y opciones dot SQL Server. Entonces recuerda los contextos DB le dijimos que necesitamos, en el contexto DB sobre creación de modelos, le
dijimos que lo lamentaría, en el constructor, ¿verdad? Tomamos opciones de contextos BB. Por lo que esas opciones realmente vienen de cualquier
opción que se definan aquí dentro, una distribución. Entonces seguimos adelante y usamos EF Core para el uso que viene la configuración de SQL Server porque vamos a estar pasando por encima de la configuración desde la aplicación cliente que está implementando esto llamado los servicios bootstrapper. Y así definitivamente tendremos que pasar. Eso es un no conflicto. Yo configuración necesita ser configuración de puntos extensiones de Microsoft, no otoño superior. Así que ten mucho cuidado con esa. Entonces podemos seguir adelante e incluir ese espacio de nombres. Y luego para los depositarios, hemos agregado alcance. Entonces estamos sumando todos ellos tienen alcance. Pero luego para el genérico, observe que estamos agregando tipo de repositorio genérico ij con nuestros corchetes angulares tipo coma de repositorio genérico, corchetes angulares. Pero entonces cada otro es la interfaz al par
de implementación sin ningún corchetes angulares. Pero seguiré adelante y añadiré aquí cualquier referencia que falte. Y con eso, y oh, lo siento, escribí el código erróneamente aquí para éste, add scoped es paréntesis abiertos y no hay corchetes angulares para el anuncio escolarizado. Está bien, así que déjame simplemente cargar eso para que puedas ver. Ahí vamos. Por lo que es paréntesis de ámbito, tipo de repositorio genérico ojo con corchetes angulares, tipo
coma de repositorio genérico con corchetes angulares. No lo hago una vez más, esos están entre paréntesis mientras que demás tendrán
los corchetes angulares rodean la interfaz y el emparejamiento de implementación. Después de todo eso, por supuesto que regresamos los servicios. Entonces solo para retroceder un poco a lo que será esta cadena de conexión, aún no
tenemos una configuración de aplicación, por lo que esto va a vivir en la configuración de la aplicación que estará llamando a este método. Y así cuando se está llamando configurar servicios persistentes, se espera que sea posible con ese objeto de configuración, que luego dará acceso a la configuración de la aplicación. Y podremos hacer posible esa cadena de conexión ¿Cuál es nuestro contexto DB? Entonces eso es lo que está haciendo toda esa línea o toda esa sección. Ahora el propósito de la fuerza usando alcance, hay tres modelos de inyección disponibles para nosotros. Tenemos en la escuela para tener singleton y agregar transitorio. Singleton significa que en una instancia de este servicio existirá, tirar toda la aplicación. Esto puede ser peligroso en función de la naturaleza del servicio. Y podría ser útil, por ejemplo, tal vez un servicio de registro que podría ser uno en sensor o toda la aplicación. Probablemente no quieras algo así para tus transacciones de base de datos. Porque entonces cuando tienes múltiples transacciones de base de datos, como que quieres que esas pasen en silos. Entonces por eso usaría alcance, lo que significa que durante toda la vida de nuestra búsqueda, estoy solicitando algo. Estoy escribiendo a la base de datos, estoy llamando a su servicio por toda la vida de esa operación. Entonces add scoped invocará y conexión a la base de datos o una instancia de este repositorio tipo hoja o cualquiera de estos repositorios, como se llama durante nuestra solicitud. Una vez terminada la solicitud, ya no estará en la memoria. Por lo que eso reduce las posibilidades de conflicto. Y luego agregar transitorio significa que cada vez que siempre hará algo nuevo, lo que significa que podrías terminar con más de lo que realmente necesitas para completar una solicitud, lo que también podría llevar a un conflicto. Por lo que una vez más, se pueden utilizar con moderación, pero dentro de este contexto, agregar ámbito es el que queremos para nuestras operaciones relacionadas con la base de datos. Ahora con todo eso hecho, hagamos una factura rápida para asegurarnos de que estamos bien en el camino y que no tengamos errores y hemos construido con éxito nuestros proyectos. Entonces, cuando
regresemos, comenzaremos a implementar o infraestructura.
18. Añade proyecto de Infrastructure (servicio de correo electrónico): Bienvenidos de vuelta chicos. En esta lección, estaremos configurando proyectos de infraestructura ahora
nuestro proyecto de infraestructura es más o menos donde se sentarán las implementaciones para todos nuestros servicios de terceros. En esta lección, estaremos implementando un servicio de correo electrónico con la ayuda de SendGrid. Y lo vamos a estar instalando en el proyecto de infraestructura. Ahora lo primero que tenemos que hacer es configurar una abstracción para los remitentes de correo electrónico, misma manera que tuvimos obstrucciones para nuestros repositorios. Tenemos una obstrucción nuestro contrato para el servicio de correo electrónico. Ahora, en esa nota, estaba mirando hacia atrás y me doy cuenta de que la estructura de carpetas aquí no es muy intuitiva para el largo plazo. Entonces me fui a refactorizar aquí porque tengo persistencia entonces tengo contratos. Pero los contratos es el término más universal porque entonces se tienen contratos por la persistencia en sus contratos para la capa de infraestructura y así sucesivamente. Entonces voy a tener que voltear. Estas carpetas son propiedad, lo que no será demasiado difícil en este llamado contratos de carpetas de persistencia. Y luego voy a llamar a los contratos persistencia. Ahora esto va a tener un efecto ondulado para todo el espacio de nombres es porque sí
queremos que nuestros espacios de nombres sean completamente representativos de lo que realmente son. Entonces tenemos contratos de punto de persistencia, no, tendremos que cambiar eso a contratos pensados persistencia. Y entonces esto se va a perder con todas las referencias del espacio de nombres. Lo siento, terrible eso. Pero es un factor que definitivamente se requiere para tengamos una estructura intuitiva de carpetas, ¿verdad? Entonces después de hacer todo eso, si hacemos una compilación, señalará todos los espacios de nombres a tope que fueron referenciados a lo largo de nuestro proyecto. Entonces, ya sabes, manera rápida de seguir adelante y arreglar esos. Pero los espacios de nombres serían buscar contratos de puntos de
persistencia en todas partes y luego reemplazarlo por el sistema de contratos dot br. Entonces puedes simplemente hacer eso y pasar meticulosamente y reemplazar cada término me hace seguro que no anula nada que pudiera ser importante. Y una vez que hayas agotado esa búsqueda, puedes seguir adelante y hacer otra factura solo para asegurarte que ya no tengas ningún error de compilación. Y una vez hecho eso, sólo
voy a cerrar todas las tinas y que se
abrieron en esa operación y luego podemos ir otra vez. Por lo que en los contratos queremos una nueva carpeta, nuestra llamada a este una infraestructura. Y luego dentro de esta carpeta vamos a añadir un nuevo contrato o interfaz. Y lo estoy llamando envio correo electrónico, sé que remitente de correo electrónico va a ser interfaz pública con un método que se va a llamar enviar correo electrónico. Y tomará un parámetro de tipo correo electrónico llamado correo electrónico. Ahora tenemos que definir cómo es este correo electrónico. Entonces voy a crear otra carpeta para modelos, ¿verdad? Por lo tanto, permítanme añadir esa carpeta. Lo estamos llamando modelos. Y luego dentro de la carpeta de este modelo, estamos agregando una nueva clase a la que estamos llamando correo electrónico. Por lo que esta va a ser nuestra plantilla, nuestro modelo para lo que debe ser cualquier correo electrónico. Y entonces este e-mail tendrá las propiedades típicas de cualquier correo electrónico que al asunto y al cuerpo, todas las propiedades de cadena. Entonces ahora que tenemos ese modelo definido, podemos seguir adelante y agregar la declaración de uso y tener eso resuelto. Antes de pasar de nuestras definiciones de modelo, tenemos otro modelo que necesitamos, y éste va a ser para la configuración de correo electrónico. Muy bien, así que va a las propiedades de manguera para una clave API de dirección y el nombre de origen, todos los cuales son cadena. Ahora que tenemos algunas cosas frescas aunque con nuestro remitente de correo, probablemente
te estés preguntando, vale, ¿por qué necesito correo electrónico? Entonces lo pone en contexto porque acabamos empezar a construir el servicio de correo electrónico sin contextos reales. Cuando alguien solicita la hoja o tal vez sus estados de aprobación cambian algo así, querrías notificarles que esta acción ha tenido lugar. No se llevan a cabo acciones raras bien relativas a las características, tenemos nuestros manejadores. Entonces cuando creas una nueva asignación en vivo,
vale, tal vez no necesites enviar un correo electrónico,
pero luego una solicitud de licencia ameritaría que se
enviara un correo electrónico cada vez que se crea uno o se actualice uno. Muy bien, así que veamos el manejador Crear solicitud de licencia donde simplemente podemos inyectar o envio correo electrónico al remitente. Y sólo lo haré usando el IntelliSense. Rápidamente, inicializa el campo. Y después dada nuestra convención de nomenclatura, simplemente
renombraré esto usando el subrayado dentro nuestro manejador después de que todo haya sido exitoso, antes de que regresemos y matemos toda la operación. Por lo que el manejador sigue subiendo a esta línea. Por lo que aparecerá un objeto de correo electrónico y luego intentará enviarlo fuera. Y nos ocuparemos de una excepción. Entonces veamos esto despacio. Por lo que var email es igual a un nuevo email, que es nuestro modelo que acabamos de definir. Tenemos los dos, acabo de poner un correo electrónico ficticio ahí cuando lleguemos a toda
la autenticación de usuario y teniendo usuarios reales enviar. Y veremos cómo obtenemos las direcciones de correo electrónico reales. Tenemos el cuerpo. Y el cuerpo de este correo solo dice su solicitud de licencia para y solo estoy poniendo uso de la interpolación para poner en el contenido inicio necesidad de terminar. Se ha presentado con éxito y el tema es solicitudes de licencia presentadas. Si lo deseas, puedes ajustar aún más la fecha poniéndote el colon D. Así que tradicionalmente dirías toString y luego especificarías el formato. Pero cuando estamos usando la interpolación en esta versión de C Sharp, podemos simplemente poner dos puntos y el formato, bueno, la cadena de formato al final de la misma. Y eso lo cuidará por nosotros. Entonces d te daría el nombre largo. Lunes, junio de esta fecha, este año. Está bien. Entonces eso es todo para o manejador saber que toda nuestra aplicación sabe del remitente de correo electrónico ojo que necesitamos para trabajar en la implementación para
que la implementación de esto viva en nuestro proyecto de infraestructura. Por lo que para empezar eso crea una nueva carpeta dentro del proyecto de infraestructura llamada comida. Y luego crea una clase ahí dentro llamada remitente de correo electrónico. Y entonces esta clase, que por supuesto estos son el público heredará de i e mail remitente. Entonces podemos seguir adelante y luego te das cuenta de que necesita una referencia a la aplicación. Por lo que tenemos que seguir adelante y añadir eso. Y con esa referencia en eso, podemos seguir adelante e implementar la interfaz. Por lo que antes de avanzar más, necesitamos saltar hacia el nuevo Git. Y necesitamos unos cuantos paquetes. Swan es las mismas extensiones de configuración que habríamos utilizado de los otros proyectos. Entonces una forma rápida de administrar proyectos comunes es simplemente ir a esta solución y decir Managed NuGet paquetes para la solución, ¿verdad? Por lo que ya tenemos algunos paquetes instalados en algunos proyectos que necesitamos en otros como éste, las extensiones de configuración. Por lo que puedo hacer click en él y veo que ya está en los proyectos de persistencia, pero quería en el proyecto de infraestructura también puedo marcarlo, click Instalar. Y así eso puede reducir la cantidad de tiempo que pasas en NuGet tratando de encontrar el mismo paquete una y otra vez. Ahora el siguiente paquete que me interesa es SendGrid. que puedas saltar a los bros y solo pisar SendGrid, y luego puedes conseguir esas últimas versiones. Por lo que querrías hacer clic en él, asegurarte de que estás tomando el proyecto correcto y luego haz clic en Instalar. Entonces después de que eso esté instalado, vamos a empezar a cablear esta clase. Entonces una cosa que voy a hacer es configurar un campo privado de configuración de correo electrónico de tipo y sobre su configuración de correo electrónico de subrayado haciendo solo lectura. Pero entonces lo estoy inicializando en el constructor con este parámetro i opciones Email Settings. Ahora permítanme explicar qué es esto similar a cómo habíamos configurado nuestra base de datos. Y dijimos que tenemos un archivo de configuración de la app que
estaremos proporcionando la cadena de conexión cuando llegue el momento. Es de la misma manera que en realidad podemos pasar por encima. Las opciones son trozos de opciones son configuraciones de la,
de todo el archivo de configuración de la aplicación, que luego se puede deserializar en un objeto entero para nosotros. Entonces lo que estamos haciendo ustedes viendo sacarme de la, de las opciones son la configuración de la aplicación, la configuración de correo electrónico, equivalente JSON, y enviarlo como este parámetro. Y entonces podemos simplemente inyectarlo y luego tenerlo como nuestra variable local, nuestro campo en nuestra clase. Por lo que esta inyección de dependencia es tan cool porque hace que
todo esté tan flojamente acoplado y maleable. Por lo tanto, sigamos con la configuración de nuestros métodos de envío de correo electrónico. Entonces la primera línea que vamos a tener es un cliente que va a llamar o inicializar un reclamo de SendGrid. Por lo que sólo vamos a seguir adelante y sumar el uso de declaraciones que faltan. Entonces después de que
lleguemos al cliente, vamos a tener que sacar todo el asunto y los dos y el cuerpo del correo electrónico de nuestro objeto de correo electrónico. Pero los dos y los de especialmente necesitan ser tipo de datos especial. Entonces voy a decir que var 2 es igual a nueva dirección de correo electrónico. Y la dirección de correo electrónico aquí viene de la cuadrícula del pecado. Tan nueva dirección de correo electrónico. Y luego vamos a tener que pasar en email dot tube. Y entonces vamos a tener que hacer lo mismo para el de. Entonces voy a decir var de es igual a nueva dirección de correo electrónico. Y en esa, vamos a ponerte un poco más en la definición donde voy a ver el correo viene de la configuración de correo electrónico punto de dirección. Y entonces el nombre sería la configuración de correo electrónico punto de nombre. Está bien. Por lo que tenemos el desde y el hasta definido. Y luego después de hacer todo eso, necesitamos ver. Mensaje es igual a varón ayudarla. Entonces Male Helper es, esa va a ser una clase estática que nos da por el pecado grid que nos permite crear un solo correo electrónico. Ahí vamos. Y ves que tienes diferentes opciones a múltiples destinatarios y múltiples correos electrónicos. Múltiples destinatarios solo estaban haciendo correo electrónico único en esta situación. Pero se puede ver que tal vez se ha enviado correo electrónico, enviar correo electrónico a múltiples enviar correo electrónico con un adjunto, etcétera. Por lo que podría definir diferentes métodos dentro del remitente de correo electrónico E. No estás confinado solo a este que estamos haciendo. ¿ Todo bien? Así que crea un solo correo electrónico. Y entonces vamos a tener que llenar este viejo según la OMS lo han declarado en el, en los parámetros para el constructor. Entonces el Fromm viene primero. Y luego decimos también, tenemos esos. Y luego el tema, puedo ver el asunto del lote de correo electrónico aquí. Y el contenido de texto plano sería el cuerpo del correo electrónico. Y se puede ver que tienen el contenido de texto plano versus el contenido HTML. Entonces en base a cómo codificas tu e-mail, podrías juntar ese e-mail en consecuencia, ¿no? Pero por ahora solo voy a decir email dot body para ambos parámetros. Entonces ahora que tenemos el objeto mensaje formulado, voy a decir que la respuesta var es igual a que los clientes envíen correos electrónicos. Entonces aquí es donde realmente vamos a mandar ese mensaje que acabamos de crear. Por supuesto, estamos consiguiendo esa línea roja porque necesitamos ser un fregadero. Y una vez hecho eso, no
necesitamos devolver un booleano basado en la respuesta. Solo puedo decir retorno si el código de estado de pensamiento de respuesta es equivalente a y solo puedo decir system.in es código de estado HTTP. Está bien. Y creo que SendGrid también atiende a alguien aceptado que haga ambas cosas, algunos regresando. Yo sólo estoy regresando. O bien está bien o aceptado. Entonces eso se va a si es cualquiera de ellos es cierto. Si no es ninguno de ellos, entonces es falso y sabrán si el correo electrónico fue exitoso o no. Pero todo el punto de esto, una vez más, voy a volver a nuestro create Tumblr y la forma en que lo envolvimos en un try catch, la API que está llamando a este manejador o cualquier código que esté llamando a este manejador no debe interrumpirse si todo lo demás. Por lo que esta es la parte más importante creando las solicitudes de permiso si los campos de correo electrónico, no
significa que deba chocar el programa. Entonces por eso estamos captando la excepción, pero no estamos haciendo nada para tirarla dicho son a través de toda la aplicación. Ahora por si fuera poco, vamos a tener archivo de registro de servicios de infraestructura, igual que con cualquier otro proyecto anterior. Por lo que tenemos la clase de registro de servicios de infraestructura que
se está agregando a esos proyectos de infraestructura. Y entonces tenemos la misma forma que han tenido todas las demás clases de distribución. Una vez más, se está inyectando la configuración yo. Y el tipo que somos, el espacio de nombres que necesitamos es la configuración de extensiones de Microsoft, no el otoño superior y lo voy a sacar a la luz cada vez porque le ha atrapado más de uno, lo siento. Por lo que vamos a ver servicios dot configurar Configuración de correo electrónico. Entonces todo esto es estudiarlo que queremos Configuración de Email. Simplemente traeré ese en B relativo a un servidor de configuración configuración Mousey correos electrónicos configuración cuando hacemos las opciones de punto, estamos viendo darme un trozo de la configuración que se parece a los ajustes de EMEA del objeto. Bueno, lo que realmente vamos a estar viendo es la configuración de punto obtiene sección. Y se verá en la configuración de la app para nuestra sección con el nombre. Me llamaremos configuración de correo electrónico cuando llegue el momento. Entonces de esa manera sabrá que formularemos
esa sección para que se vea igual a lo que estamos esperando que se vea la clase. Por lo que sólo se serializa automáticamente en esa clase codificada dura son fuertemente vidrio tipado en lugar. Siguiente parada vamos a ver servicios que agregan transitorios. Ahora recuerda que estaba hablando de los diferentes modelos. Tenemos. Singleton, esculpir y transitorio. Por lo transitorio significa que cada vez que
me llamen, voy a ser una instancia totalmente nueva. Entonces estamos viendo que cada vez que se llame al remitente de correo electrónico, dame una instancia totalmente nueva del, de la clase
de remitente de correo electrónico. De acuerdo, así que adelante e incluye cualquier referencia que falte. Y entonces podemos cerrar ese y luego regresamos los servicios. Entonces eso es todo para nosotros sentados nuestra infraestructura, al
menos ese es un nivel muy básico. Una vez más, cualquier contrato que tengamos que definir para una operación de terceros se definirá en nuestra aplicación, pero implementado en nuestra infraestructura.
19. Crear y configurar la API de la aplicación: Bienvenidos de vuelta chicos. En esta lección, estaremos configurando nuestros proyectos API. Por lo que tenemos la fundación ya en la forma de la infraestructura, los proyectos de persistencia o dominio y nuestros proyectos de aplicación. El caso es que estos evolucionarán con tu aplicación. Por lo que estas capas son estos proyectos. No están puestas en piedra, pero al menos sentamos las bases para construir una API encima de ella que
en realidad estará a cargo de la información tóxica entre cualquier aplicación cliente y estas capas para nosotros. Entonces empecemos a configurar estos proyectos API. Vamos a colocarlo en nuestra carpeta llamada API. Vamos a Agregar Nuevo Proyecto, encontrarlo fácilmente, solo podemos buscar en la lista de API. Y estamos usando la plantilla de proyecto C-sharp API, y estamos llamando a esta API de punto de gestión de puntos de HR. Adelante y hit Next, y estamos usando dotnet cinco son la última versión porque.net es muy compatible con versiones anteriores. Entonces la mayoría, si no todo lo que estamos haciendo este curso será compatible con futuras versiones de dotnet y seguiremos con la configuración y crearemos. Ahora este proyecto API es bastante desnudo. Sí nos da algún código de muestra en forma de este controlador de pronósticos meteorológicos, que no necesariamente necesitaremos. Antes de seguir adelante, agreguemos las dependencias que tendrá este proyecto API. Y esas dependencias incluyen nuestro proyecto de aplicación o proyecto de infraestructura y o proyecto de persistencia. Aproximadamente cualquiera de los proyectos en los que pondríamos estos servicios de
registro métodos en. Esas van a ser dependencias para la API porque la API necesita poder registrar estos servicios en su base de código. Por lo que sólo podemos seguir adelante y agregar estas referencias de proyecto. Y una vez que lo hayamos hecho, podemos continuar con nuestra configuración. Entonces cuando hablamos de crear y configurar hemos creado no, necesitamos configurar. Entonces en términos también de las cosas que tienen dependencias de lo que vamos a estar sentados en la API. Estamos hablando de la configuración del correo electrónico. Por lo tanto, recuerda que en nuestra infraestructura habríamos hecho mención
del remitente de correo o habríamos implementado remitente de correo otro y
es dependiendo de Ajustes de Email viniendo a través de opciones de IA, ajustes de
correo electrónico, que ya discutido va a estar viniendo de nuestro archivo de configuración de aplicaciones. Otra cosa que necesitamos configurar es por nuestra capa de persistencia. Lo siento, solo estoy recogiendo salvajemente para capa de persistencia o DB. El contexto depende de una cadena de conexión que volverá a venir de la API. Por lo que nuestro archivo de configuración de aplicaciones aquí, tendremos bloques o secciones que tengan esas definiciones. Entonces vamos a trabajar en el primero, y esa es nuestra cadena de conexión. Entonces por encima de esta definición de registro aquí, solo
voy a presionar Enter y luego voy a poner en mi sección de cadenas de conexión. Entonces cadenas de conexión. Y entonces tiene el mismo nombre de lo que nos habríamos referido en la redistribución de persistencia, ¿no? Obtener cadena de conexión. Y luego es dejar cadenas de conexión de gestión. Entonces cadena de conexión sabe buscar en la aplicación settings.js ON buscar cadenas de conexión, obtener esa por nombre. Y su definición aquí es que estoy usando el servidor DB local MS SQL, así que tienes que escribirlo igual que como lo ves en la pantalla aquí. Eso está integrado en Visual Studio. Base de datos es igual a, y estoy llamando a mina HR underscore leave management underscore DB. Puedes llamarlo otra cosa si lo deseas. Y aparte de eso, y cada uno está separado de punto y coma y luego tenemos conexión de confianza es igual a punto y coma verdadero múltiples conjuntos de resultados activos es igual a verdadero. Entonces esa es tu cadena de conexión. Ahora para la configuración de correo electrónico, vamos a tener una nueva sección llamada Configuración de correo electrónico, y luego tenemos esa clave API. Entonces necesito hacerlo, necesitamos ir con el SendGrid, luego obtiene nuestra clave API repentinamente, poniendo un soporte de lugar para nulo. Y entonces tenemos el nombre de, ahí parecerá venir el correo electrónico y luego la
dirección de desde no será respuesta en leave management.com o leave reply. No hay respuesta, lo siento, en Ahrq.com, lo que sea que quieras ahí. Ahora por si no estás muy familiarizado con lo que es SendGrid. Se trata de un producto de dos niveles que nos permite acceder sobre Paul para el sistema API de correo electrónico. Y solo puedes empezar de forma gratuita. Es libre hasta cierto punto, claro, y no quieres abusar de ella. Pero una vez que te registres, te
darán esa clave API, que es lo que puedes pegar ahí mismo en la configuración del correo electrónico, en la app settings.js IN. Podemos hacerlo más adelante. Por supuesto, no quiero que veas mi llave porque la clave es privada, así que quieres asegurarte de que mantengas la privacidad con eso. Entonces ahora que tenemos nuestro AP settings.js, archivo
JSON al menos o equipado con el mínimo cuatro o distribución de nuestros servicios. Vamos a saltar al startup.js. Por lo que no son algunos del archivo startup.js. Es básicamente el contenedor que dice que estas son todas las dependencias que mi aplicación necesita saber. Y los estoy haciendo accesibles a través de la inyección de dependencia. Está bien. Hace tiempo que hablamos de inyección de dependencia. Y cada uno de estos archivos de registro básicamente
nos está permitiendo registrarlos como dependencias en una aplicación. Entonces lo que necesitamos hacer es dejar
saber a nuestra API que se trata de dependencias que cada uno debe conocer. Entonces cuando hablamos de la figuración del ícono, notan
que se está pasando a la startup mientras se está inyectando directamente en la startup. Y eso nos permite entonces pasar ese objeto de configuración a otras partes de nuestra redistribución. Entonces lo habríamos visto en la infraestructura si no me equivoco, ahí vamos. Yo configuración necesita la configuración y sí la necesitamos para la persistencia también. Entonces basta de hablar, entremos a la acción. Por lo que en nuestro método de configuración de servicios, queremos incluir estas tres líneas, que son las Configurar Servicios de Aplicaciones, configurar servicios de infraestructura, y configurar servicios persistentes, y configurar servicios persistentes,
todo lo cual sabemos embarcación proveniente de nuestros o servicios a distancia, archivos
de redistribución de servicios en los diferentes proyectos. Entonces aquí está el catch-all. Por lo que solo seguirá adelante y agregará las dependencias y espacios de nombres que falten para cada uno de estos. Tenga en cuenta también que tenemos que pasar en esos objetos de configuración. Muy bien, entonces lo inyectamos en la startup y luego lo podemos pasar para que cuando esos métodos estén siendo llamados en sus respectivos proyectos y sí tengan las herramientas necesarias para acceder a lo que necesitan para acceder desde nuestra app ajustes. Otra cosa que queremos configurar en esta API es, o lo que llamaremos política CORS. lo que nuestra política de curso básicamente determina cómo la API permite que otros clientes interactúen con ella. Entonces en este momento esta política es bastante abierta. ¿ Dónde ve los servicios dot-dot-dot cores builder permite cualquier origen, permite cualquier método, permite cualquier encabezado. Entonces en nuestro método de configuración, vamos a bajar y sólo voy a pegarlo aquí entre Autorización de
uso y uso endpoints. Y esto se alivia ni que deba utilizar esa política en todo momento. Ahora hemos llegado un buen camino con todas las configuraciones. Nos queda un paso más para esta lección, y es generar nuestra base de datos. Por lo que hemos hecho toda esta configuración. Tenemos la capa de persistencia ahora en realidad la tenemos cableada. No, en realidad estamos pasando por encima de la cadena de conexión. Entonces ahora sabe que cuando existe, en qué servidor debería existir y cuál debe ser el nombre de la base de datos. Entonces consigamos los nuestros para venir configurando nuestra base de datos. Por lo que necesitamos ejecutar las migraciones. Y solo estoy haciendo una compilación rápida que fue exitosa. Por lo que antes de pasar a las migraciones, necesitamos tener acceso a nuestra herramienta EF Core. Entonces entra en Gestor de paquetes, todo eso. Se buscará herramientas. Y bastante seguro, herramientas de
Microsoft dot Entity Framework Core es la segunda en los resultados de búsqueda. Entonces voy a seguir adelante e instalar eso en mi proyecto API. Y con esa configuración, también
voy a establecer el proyecto API como mis proyectos de puesta en marcha. Entonces puedo hacer eso desde este desplegable, Muchos arriba, o podría hacer clic derecho en él y decir establecer como proyecto de inicio. Ahora con todo eso hecho, podemos proceder a nuestra Consola de Gestor de paquetes. Entonces si no lo tienes en tus elementos de menú o como barra de herramientas como yo, entonces siempre puedes ir a Herramientas, ir al gestor de paquetes NuGet, y verás la consola listada ahí. En esta consola Package Manager, vamos a agregar SHE migración y podemos darle un nombre para que pueda llamarlo inicial crear migración inicial, algo que indique que fue la primera, ¿verdad? Otra cosa que te gustaría hacer es cambiar los proyectos por defecto. Por lo que el proyecto por defecto prácticamente necesita ser el mismo proyecto donde su contexto DB es algún ajuste que sea el proyecto de persistencia. Y para contextos, recuerda que en nuestro proyecto de persistencia o un contexto DB, habíamos dicho que el modelo en la creación no modelo, dijimos aplicar configuraciones desde ensamblado y donde sea que este sea ese ensamblado,
Eso es más o menos lo que esa línea estaba especificando. Por lo que necesitamos aquí nuestro directorio de migraciones. Por lo tanto, asegúrate de que eso esté establecido. Si no lo haces, obtendrás un error desagradable. Un barco se está poniendo en el proyecto objetivo equivocado. Entonces cuando sigamos adelante y sumamos que la migración va a hacer su magia. Y luego obtenemos este archivo de migración, que nos está dando todas estas tablas que habíamos creado inicialmente. Recorrido tan rápido por nuestro archivo de migración, si no te resulta tan familiar, tenemos un método op y un método add-on. El otro método básicamente tiene código y si lo acabas de leer como desarrollador C-sharp, como desarrollador SQL, ves lo que está haciendo. Es crear una tabla con nombre, con estas columnas, con todas esas fijaciones en cada columna. ¿ Todo bien? Y entonces el abajo significa que si deshaces esta migración, estas son las cosas que harán. Dejará caer las mismas mesas. Entonces por cada arriba hay adulto. Por lo que ahora que tenemos nuestro archivo de migración existente, podemos seguir adelante y actualizar la base de datos. Entonces la base de datos básicamente dice que si no existe, se crean. Si existe, entonces aplicaré los cambios. No existía. Por lo que sí lo creó sólo nieve. Y para comprobar y verificar que está creado, podemos ir al Explorador de objetos de SQL Server, expandir y expandir la barra de base de datos local y Mrs Hill local DB hace el servidor que indicamos. Y si estás usando un servidor diferente, entonces puedes proceder a ese servidor en particular. Y cuando nos expandamos, es una base, veremos nuestra gestión EHR DV dB. Y si ampliamos las tablas, veremos nuestras tablas que se definieron en consecuencia. No vimos ningún peligro. Todas las mesas están vacías. Posteriormente cuando empecemos a construir nuestra propia aplicación, podemos seguir adelante y ver cómo los datos ISI. Pero por ahora, esta es misión cumplida.
20. Implementar los controladores de la API finos: En esta lección, estaremos buscando agregar servicios de mediador a nuestra API. Ahora, el contexto para esto es que los medios de comunicación nos permiten especificar comportamientos en nuestra aplicación basados en una respuesta sobre tipo de relación manejador. Una de las consecuencias o beneficios de esto es que podemos enviar viejas muchas de las operaciones pesadas desde nuestro código de llamada, que en este caso va a ser nuestro controlador. Y podemos abstraerlo a otro lugar. Entonces el controlador realmente solo sabe que construyo una solicitud y la envío para ser manejada. Entonces para el contexto, tengo en pantalla el controlador del proyecto anterior, que es inspiración para nosotros rehaciendo este sistema de gestión de necesidad. Y aquí verías que no tenemos controladores delgados, tenemos controladores de grasa. Entonces son controladores, de verdad. Esos exactamente lo que sugiere el nombre, controla el flujo y todo lo que hace la aplicación. Por lo que responde a las solicitudes de datos de un usuario, etcétera. Ahora, en el proyecto más antiguo, teníamos lo que llamamos controladores de grasa, o estamos haciendo todo dentro del controlador. Una vez más, esto funciona. Entonces no es que no vaya a funcionar. Si se hace eso vamos a trabajar. Pero, ¿es el Holman Tenable mejor practicado es éste? Porque si quisiera verificar que estas operaciones se están haciendo con éxito, tendría mucha
unidad de dificultad probándolo de esta manera porque esto no está en un sindicato, esto es suficiente dentro de nuestro controlador. Por lo que eso aumenta mi incapacidad para probar las partes de la aplicación para asegurarse de que estén funcionando correctamente. Y aumenta mi tiempo dedicado a la solución de problemas y pruebas de regresión y todas esas cosas. Aquí está comprobando si algo existe y si no existe, está regresando no teléfono. Y luego está haciendo mapeo y está haciendo un hallazgo, y luego está devolviendo la vista. Lee Andrew, solo quiero el menor número de colores posible sin lógica empresarial. Esta es alguna forma de lógica empresarial. Realmente no queremos eso en nuestra aplicación. Muy bien, aquí hay otra situación en la que estamos creando nuestro disco y simplemente estamos haciendo demasiado en esta opción. Entonces esas son las cosas que queremos reducir cuando
hablamos con tener controladores delgados. Entonces empecemos instalando mediador en nuestros proyectos API. Ya conoces el taladro, solo puedes hacer clic derecho ir a NuGet. Buscamos mediador e adelante e instalarlo. Una vez que hayas completado esos pasos. Una vez que hayas terminado con eso, sigamos adelante y agreguemos un nuevo controlador a nuestro proyecto. Se trata de un controlador MVC y queremos un controlador API con opciones de redireccionamiento. Vamos a empezar con la más fácil,
que es tipos de licencia y seguir adelante y agregar. Ahora vamos a explorar cómo los medios de comunicación nos van a ayudar, ¿verdad? Por lo que ya tenemos las buenas opciones básicas que se están generando para nosotros por suerte. Pero entonces lo que necesitamos hacer es inyectar nuestro objeto mediador en nuestro controlador. Entonces vas a trabajar en el derrame cerebral. Y luego vamos a hacer referencia a I. Mediador requerirá que tengamos esa declaración de
uso así como inicializar ese campo. Y entonces podemos empezar a usar este medio para oponerse a las calles Arcbest o causar nieve. Recorrido rápido por este controlador. Y en este punto, por supuesto, estoy asumiendo que tienen cierta familiaridad con los controladores. Y por extensión, desarrollo de API, cuando queremos obtener la lista de registros son todos los tipos de licencia en la base de datos
van a golpear este método que es sólo el obtiene sus tipos de licencia de slash API. Eso es lo que se espera que nos llegue, pero todos los tipos de hojas. Y entonces cada uno de estos métodos llevaría a las otras operaciones de crud que son tira el puesto, el delete. Es para actualizaciones. O si no estás tan familiarizado con lo que estoy hablando, te animaría a ir y revisar mis cursos de desarrollo de API para que puedas ponerte al
día a apreciar plenamente cuáles son
las entresijos detrás de estos métodos y cómo funcionan . Entonces sigamos por los get's que se espera devuelvan todos los tipos de hojas en la base de datos. Vamos a tener un código que se parezca a esto. Vamos a tener tipos de licencia var es igual a una espera. Entonces el método enviar encontrado en nuestros medios a objetar y todo lo que exactamente estamos enviando? Si miras la sobrecarga, está esperando un objeto de tipo o un objeto con los departamentos se llaman solicitudes, por lo que no sabe qué tipo de solicitud va a enviar la solicitud. Y la expectativa es que se va a conseguir algo que se pueda almacenar dentro de los tipos de hojas. ¿ Conoce qué solicitudes estaríamos enviando? Mientras salta de nuevo a las características de nuestro proyecto de aplicación, deje tipos y consultas. Veremos aquí que tenemos la solicitud get leaf type list, cual se espera que devuelva la lista de detalle tipo hoja. Entonces en nuestro controlador de tipos de hojas, diría que estoy enviando un nuevo objeto de solicitud de lista de tipos. Y luego seguir adelante e incluir cualquier extravío usando declaraciones. Y luego seguiré adelante y cambiaré el encabezado del método a resultados de acción de tarea asíncrona pública, lista hojeados detalles. Entonces ahora sabe que se espera que devuelva unos resultados de acción que tenga esa lista de tipos de hojas. Por lo que esta declaración de devoluciones ya no es válida ya que no, estaré devolviendo tipos de hojas y mira que dos líneas. Contextos. Simplemente lo voy a comparar con el viejo código o es nuestra
antigua opción habría tenido la variedad de tipos. En realidad habría orquestado el llamado a las unidades de trabajo para conseguir los registros, traerlos directamente, buck. Y luego estaremos realizando el mapeo porque estaría devolviendo los
objetos de dominio cuando quisiéramos que las VMs sean contextos para que sea lo mismo que un DTO. Y entonces estaríamos haciendo toda esta operación dentro de la propia acción antes de devolver la vista. En el nuevo paradigma, lo que estamos haciendo es solo que estamos dejando que los medios sepan que estamos solicitando la lista tipo hoja o manejador va a realizar todas las operaciones, está pegando todo el mapeo y la consulta y todo, y está devolviendo sólo los objetos que necesitamos conocer. También lo son la API nunca interactuaría con los objetos de dominio reales que provienen de la base de datos. Hacemos toda esa transformación antes de que llegue todo el camino de regreso. Así que avancemos un poco a donde ya he escrito el código, pero como de costumbre, lo pasaré despacio y te explicaré cada línea para que puedas apreciar plenamente lo que está sucediendo. Se puede hacer una pausa según sea necesario y replicar. Y vamos a pasar juntos de todos modos. Muy bien, así que un ajuste rápido a la HTTP GET He limitado retorno on, bien, con tipos de hojas. ¿ Todo bien? Y te das cuenta una vez más, tarea, acción resultados listan los cinco dB HL. Entonces esto está siendo muy explícito en cuanto a qué tipo de datos
va a devolver nulo para el HTTP GET con un ID. Una vez que he hecho tarea de código similar, muy similar, los resultados de
acción dejan la diabetes. Por supuesto que tiene que ser asíncrono. Y decimos que el tipo de hoja var es igual a y luego esperamos al mediador Dotson con la nueva solicitud. Por lo que recuerda que se manejará la solicitud. Mediador se está ocupando de esa parte. Tenemos que asegurarnos de que utilizamos la solicitud correcta en base a lo que queramos. Entonces en esta situación, la solicitud es obtener hoja tipo bt EverQuest, que es donde está consiguiendo el tipo de hoja particular con todos
los intrusos y cualquier otro fondo colgando o requerimientos que pudieran estar ahí. Para los detalles. También necesitamos darle el valor id que vas a estar obteniendo porque en nuestro manejador, se basará en gran medida en el ID para saber qué registro se necesita recuperar. Y luego regresamos, acuerdo, con el tipo de hoja. Ahora en el post, tenemos unas cuantas líneas más y en realidad es solo yo mostrándote cómo puedes romperlo de todos modos, pero no es absolutamente necesario. Porque justo de la misma manera que todo podría haber ido en 19 y simplemente creamos el nuevo objeto aquí mismo. Yo podría haber hecho eso dentro de éste, medios para enviar línea. En cambio. No obstante, dije comando var es igual a un nuevo crear comandos tipo hoja. Por lo que el método post está diseñado para la creación. Muy bien, así que déjame empezar desde Desire2Learn tabla BAC, pero yo tenía de mí mismo ahí resultados de acción asíncrona tarea pública. En realidad, no necesariamente hay que ver cuál es el tipo de retorno. Sí ayuda con la documentación sobre el gueto a jadear. Entonces lo volvería a poner. Independientemente de esta situación, la respuesta sería un int. Entonces pudimos ver int, pero como dije, no es absolutamente necesario. Entonces voy a seguir sin que sea necesario ahora mismo y más adelante veremos por qué habría sido buena idea ponerlo. Entonces tarea, acción, resultado, post, y lo estamos haciendo desde cuerpo, y luego estamos usando el tipo de detalle específico para la operación. Entonces recuerda que discutimos el que te pones granular. Déjalo general. Bueno, esta es una situación en la que evitaríamos
sobrepublicar al conseguir granular porque entonces cuando giran, cuando envían información tipo hoja, lo que aceptamos a través de esta opción se limita
al propiedades dentro del tipo que especificamos. Entonces a diferencia de tipo hoja detalle o hoja tipo BTO, que tiene más detalles son más campos que crean. El tipo de hoja solo está diseñado para aceptar los puntos de datos que
sabemos que absolutamente necesitamos para que se cree nuestro tipo de hoja, por lo que cualquier otra cosa será ignorada. Entonces cuando formulamos este comando, dijimos nuevo crear hoja Comando, D, comando. Necesita dejar ese objeto detalle. Entonces pasamos en ese objeto. Y entonces nuestra respuesta es relativa a lo que regresa el mediador. En esta situación, nuestra respuesta fue int, porque eso es lo que habíamos dicho. Al crear el tipo de hoja, simplemente devuelve su ID. Entonces ese fue el manejador que diseñamos para ese tipo de solicitudes. Entonces cuando regresemos todo k con la respuesta, eso estaría bien con la identificación de la hoja. Ahora pasando al put,
put se utiliza para la actualización, una vez más está en los resultados de acción de tarea. Y entonces es por defecto tener ese parámetro ID y cambiamos de perímetro del cuerpo a ser el tipo de hoja DTO. Entonces lo hicimos, habíamos discutido desde antes que la hoja tipo BTO, no
nos pusimos demasiado granulares con eso. Tengo una etiqueta div de actualización, div A diferente de todo lo demás. Eso está bien. Entonces en esta situación, estamos aceptando todos los temores posibles se podrían actualizar. Y definitivamente necesitamos la identificación dentro de este objeto, razón por la
que estamos logrando eso. De hecho, ¿se aturde este ID es opcional. Por lo que en realidad podría simplemente decir, no
necesito un parámetro ID. Entonces cuando llamas al puesto, no
tienes que llamar a una identificación. Y entonces este comentario en realidad sólo actualizaría los comentarios establecer uniformidad. Entonces resultado de acción tarea, poner una hora buscando es los contextos corporales con el tipo de hoja DTO. Recuerda, toda nuestra validación está sucediendo dentro de nuestros manejadores. Entonces eso es aún menos. Menos cosas rasgaron balas aquí mismo. Cuando estamos hablando se peinó el ID, ¿existe el DNI? Todas esas cosas están sucediendo dentro de nuestro manejador, entre el manejador y son validaciones fluidas en realidad. Y si algo se siente de ese lado, entonces toda esta operación fallará. De todos modos. Veremos cómo manejamos las fallas más adelante. Pero por ahora solo queríamos conseguir un control sobre cómo deben verse nuestros controladores. Entonces cuando enviamos el comando para actualizar, no
cableamos el jabón para devolver nada, al
menos nada útil, ¿verdad? Acabamos de decir Unit dot value unit representaba un vacío, así que tuvimos que devolver algo, pero acabamos de decir, vale, sólo vas a devolver algo arbitrario para decir que fue exitoso. Y así la respuesta HTTP que corresponde con un put suele ser ningún contenido, cual es una herramienta para, de acuerdo, así que podemos simplemente devolver que no hablamos con nosotros y la respuesta a cualquier variable. Eliminar se ve similar. Delete toma un parámetro ID, tarea, resultados de
acción, delete int id. Y luego tenemos el comando que solo toma el ID, y luego enviamos el comando y regresamos o todo el contenido. Entonces si es que quieres que todo sea solo dos líneas, entonces eso es tan fácil como tomar el comando, ponerlo en el mismo parámetro. Y todo puede ser de dos líneas. Está bien, así que solo te estoy mostrando la diferencia, la gran diferencia entre este controlador que está haciendo todo lo que este controlador está haciendo con todo el código, bien, con las ediciones estaban haciendo validaciones aquí. Para el Delete, estamos haciendo alguna forma de validación. Nuevamente, todas esas cosas son nulas, obstruidas viejas en otras partes de la aplicación. Y nuestro controlador puede hacer exactamente lo que se supone que debe hacer, que es recibir una solicitud, hacer una llamada para hacer alguna operación, y luego devolverle sus datos. Ahora aquí está mi reto para ti. Adelante y cablear los otros controladores para los otros tipos, para las características. Por lo que tenemos tipos de hojas se hacen. Adelante y prueba las solicitudes y las asignaciones de licencia. Se pueden, por supuesto, crear opciones personalizadas relativas a lo que es que la operación necesita llevar a cabo. Pero por ahora, te dejaré hacer eso. Entonces voy a volver en el siguiente video. Vamos a comparar notas.
21. Terminar los controladores de la API finales: Está bien, Así que esto es más de un video de revisión que un video de escucha. Sólo ten unas cuantas cosas en las que quiero enfocarme en esta lección que
probablemente intentaste y probablemente tuviste programas con un si no entonces elogios a ti. Entonces empecemos con el controlador de asignaciones de licencia, de verdad y de verdad, este es un control que va a ser bastante idéntico a nuestro control de tipos de licencia porque realmente y verdaderamente solo estamos haciendo operaciones crud aquí. Estamos consiguiendo la lista donde llegar por DNI. Y por supuesto si no lo completaste, siempre
puedes simplemente hacer una pausa y seguir adelante y replicar como me ves pasando. Hacemos lo mismo para el puesto. Por lo que notarás que todo lo que más o menos dijo solicitudes de licencia está notando asignación de licencias. Casi podrías decir que podrías haber creado un nuevo controlador, copiado todo desde el controlador de tipos de hojas, pegado en el nuevo controlador y luego simplemente vigilado el tipo de hoja con asignación de permisos o tipo con la palabra asignación. Solo te estoy dando propinas todo lo que podrías haber hecho esto con bastante rapidez y bastante eficacia, ¿verdad? Porque éste es bastante idéntico a los tipos de hojas. Solicitudes de dejar, por otro lado, tiene una pequeña sorpresa. Y eso está en la forma de la actualización, ¿no? Entonces una vez más, pasando por lo suficientemente despacio, prácticamente
me replican las opciones de los tipos de hojas sobre en las solicitudes de licencia. Por lo que la mayor parte del contenido de este controlador es idéntico a los otros dos, con excepción de nuestra operación PUT. Y si te das cuenta y miras muy de cerca, yo diría poner operaciones x2. Por lo que todos los demás sólo en un puesto operación uno, actualizar los puntos finales. Pero entonces en el caso de la solicitud de licencia, habíamos hecho espacio para dos tipos de actualizaciones. Uno donde es un actualizaciones regulares. Y note que esta vez sí tenemos el parámetro ID en la puesta. Y eso es porque nuestro mando solicita permiso pide el DNI y un detalle, eso está bien. Pero una vez más, estos diferentes sabores son relativos a cualquier estilo que pienses. Escenario mucho más fácil. Entonces solo te estoy mostrando diferentes opciones. No digo que así sea como debe ser. Tienes las diferentes opciones. Usa el que sea mejor para tu situación y tu proyecto. Ahora en esta situación, una vez más, sí
tenemos el parámetro ID que podemos con el comando y construimos una solicitud de permiso DTO. No obstante, el otro escenario de actualizaciones tendría sólo un estado de aprobación de cambios para nuestras solicitudes de licencia. Entonces en ese caso, creé una aprobación de cambio de endpoints personalizada. Entonces para llegar a este, dices api slash Solicita aprobación de aguanieve de Controller. Y de verdad necesito el DNI. Entonces déjame seguir adelante y agregarlo a la raíz para que se cambie aprobación del valor ID de Slashdot. Ya que también he actualizado la documentación en consecuencia. Y necesito poner ese parámetro ID, buck. Tan complicado dicho antes, ponlo de nuevo y construye mis objetos de solicitud, bien, o mi objeto de comando más bien. Entonces solo te estoy mostrando todas las consideraciones que hay que hacer. Qué al final del día, nuestros controladores son delgados y los beneficios de esto pueden estar viendo, bien, entonces tres líneas, pero todo eso funciona o en los videos anteriores, solo para que pueda poner tres líneas aquí. ¿ Por qué Titus no puso toda la lógica aquí? Cuales otra vez, entiendo completamente porque funcionaría. Pero al final del día, cita, es mucho más comprobable y no tengo que probar el controlador para saber si obtendría los resultados de este punto final. En cambio, puedo ir a probar al manejador que se supone está devolviendo esos resultados. Y si el manejador funciona, entonces el punto final funcionará. Entonces, ya sabes, es solo cambiar tu enfoque de ser más compacto a ser un poco más modular y
difundir el código y la responsabilidad a través de más agradables para que puedas tener una mejor apreciación o un amargo control sobre lo que cada componente hace ileso, todos atados juntos.
22. Datos de semena en las semillas: Muy bien, así que estamos terminando con nuestras operaciones relacionadas con API. Y en esta lección, lo que queremos hacer es sembrar algunos datos predeterminados en nuestra base de datos. El siguiente paso, por supuesto, sería probarlo, pero entonces siempre es bueno tener algunos datos de muestra para que
podamos hacer las operaciones de lectura con bastante facilidad y eficacia. Entonces para ver datos en nuestra base de datos, vamos a ver cómo logramos eso con Entity Framework. Ahora ya he hecho uno y tengo los otros dos hechos por un, para que podamos hacerlos juntos. Pero empecemos yendo al proyecto de persistencia, agreguemos una nueva carpeta llamada configuraciones, y ahí otra carpeta llamada entidades. Y luego vas a tener un archivo de configuración por entidad. Por lo que más o menos este archivo de configuración permite poner en cualquier Entity Framework relacionado o cualquier base de datos más bien, configuraciones son valores predeterminados o cualquier regla que se quiera repasar en la tabla particular en la base será entonces todo el código se escribe cortesía de EF Core. Entonces veamos el que ya he hecho, y eso es para la configuración de tipo leave. Para que puedas hacer una pausa, quitarte esto, y luego podemos ir por los pedacitos y pedazos juntos. Entonces tenemos la configuración del tipo de hoja y luego está heredando de I configuración de tipo
entidad relativa al tipo de clase con el que estamos tratando, que es el tipo de hoja. Entonces todo en esta base de código básicamente va a ser relativo al tipo de hoja. Entonces una vez que hagas eso, vas a terminar con, te
va a pedir en
el parlamento la interfaz y entonces eso generaría este trozo de método para ti. Entonces dentro de este método stub, vamos a tener el vacío público configure. Y entonces tenemos ese int. Es todo eso realmente se genera para ti. Por lo que cuanto más las partes principales de la misma, que es en lo que estarás construyendo o escribiendo, estarían en esta sección Builder. Por lo que diríamos constructor tiene datos. Y entonces diríamos dejar tipo o crea un nuevo objeto. Entonces este es un método tiene la muerte es un método que tiene llaves abiertas y cerradas. Y luego ahí dentro vemos nuevo tipo de hoja y luego llenamos un objeto. Entonces este es el objeto de dominio que estamos viendo tus ID uno, tu predeterminado es entrar en bases de datos 10 y tu nombre es vacaciones. Y luego tantos como necesites, realidad
puedes simplemente separar en coma cada inicialización de un objeto o instanciación de un objeto dentro de todo este bloque. No, no he hecho los otros dos. Entonces los voy a hacer un poco desde cero. A pesar de que por no, probablemente lo hiciste ya con el tipo de hoja. Bueno, eso está bien. Entonces para la configuración de asignación de licencias, está
heredando, pero no hay declaraciones de uso en absoluto. Entonces por eso estás viendo la línea roja. Entonces usaré punto de control usando Microsoft Entity Framework Core, la referencia de dominio, y luego implementaré la interfaz que genera ese stub de método para mí. Pero no hay nada ahí para que yo configure para la asignación. No tengo un requisito para la asignación por el momento. Está bien. Por lo que no veo ninguna asignación de licencias. No estoy cambiando nada sobre los valores predeterminados en la estructura de la mesa. No estoy haciendo nada más. Entonces como dije, esta configuración se puede usar para mucho más que solo sembrar datos. Y si quieres una mejor comprensión de lo que es capaz, siempre
puedes consultar todo mi curso de Entity Framework Core. Muy bien, entonces haremos lo mismo por la petición. Y solo dejaremos eso ahí una vez más, no
tenemos ninguna solicitud de permiso que necesitemos como valores predeterminados, pero sí tenemos algunos tipos de hojas por defecto, así que eso es suficiente por ahora. Al menos podemos ejecutar la API y hacer solicitudes GET en esta tabla y verificar que está funcionando. Por lo que el siguiente paso después de escribir este código sería ir a nuestra consola Package Manager y necesitamos agregar migración para sembrar tipos de licencia. Entonces una vez que hagas eso, llegamos a un archivo de migración que nos está dejando saber que va a estar insertando esos datos en la base de datos para nosotros. El siguiente paso, como sabemos, sería actualizar la base de datos. Está bien, genial. Por lo que esta vez no vamos a ir directamente a
la base de datos para verificar que estos fueron creados. Lo que haremos es probar nuestra API. Entonces nos vemos en la siguiente lección.
23. Revisión de Swagger API: Muy bien chicos, bienvenidos de nuevo. Entonces en esta lección vamos a estar viendo una, probando nuestra API y a documentarla. Por lo que el pool clave que engloba ambas tareas se llama Swagger. Swagger es una herramienta de documentación de API de código abierto basada en los estándares de API abiertas. Ahora sale de la caja para dotnet cinco proyectos API. Entonces si saltamos para arrancar y desplazamos un poco de quién ver aquí que estamos agregando el swagger Biblioteca Ginn, que crea ese doc Swagger con una información API abierta. Entonces podemos cambiar todas estas cosas. Simplemente puedo ver API de gestión de licencias de RHH. Darle un título, darle una versión. Puedes agregarle otros nodos, descripción de
contacto, etcétera, etcétera. Por lo que es una herramienta muy poderosa. Y como dije, sale de la caja y no pusiste eso ahí. Y otra parte que verías es aquí abajo en el método configure donde dice, si estamos en desarrollo, entonces usa swagger y API. Entonces si quieres usar swagger, porque sé de corporaciones que se usó el futbol como su documentación en producción, entonces siempre puedes usar esta sal de ese if statement y en realidad usarla independientemente de tu entorno. Está bien, para que puedas seguir adelante y hacer ese cambio. No, llevemos a cabo nuestros proyectos. Entonces solo voy a golpear a F5 con el proyecto API como proyecto de startup. Y eso nos da como resultado conseguir este hermoso documento que nos muestra todos nuestros puntos finales potenciales y cómo se les puede llamar. Aviso aún tenemos el pronóstico del tiempo. Podemos borrar eso después, pero solo te estoy mostrando que no hicimos mucho. Todo lo que hicimos fue configurar nuestros controladores, escribir el código que sabemos que necesitamos escribir. Pero aquí está este hermoso documento que nos muestra todo sobre nuestra API. Entonces si hago clic en uno de estos, se extiende y me muestra exactamente lo que puedo esperar. Entonces este endpoint, que es R, este comportamiento api slash leave asignaciones, que es el get que obtiene todos los registros en la tabla de asignaciones de licencia. Me va a dar un código 200 de éxito. Y este es un adelanto del objeto que estaría recibiendo buck. Por lo que una vez más, siempre voy a volver a los detalles y lo granular que te metes en lo que quieres mostrar. Observe que en este detalle en particular, tenemos el ID, tenemos el número de días, tenemos el tipo de hoja con su propio ID, el nombre, y el valor predeterminado es, entonces tenemos el tipo de hoja ID. Entonces podrías estar mirando esto y decir, bueno eso es algo redundante. Si ya tengo el objeto tipo hoja, no
quiero difícil repetir aquí el ID. Y eso sería una declaración de miedo, ¿verdad? Entonces, ya sabes, no nos pusimos muy granulares con la lista de asignación de licencias DTO. En esta situación, sólo utilizamos el nuevo detalle de asignación. Por lo que podríamos estar enviando demasiados detalles son demasiados campos en esa respuesta. Podemos ajustar eso en consecuencia. Entonces echemos un vistazo a las solicitudes de licencia. Las solicitudes de licencia tendrían ID, el tipo de hoja, la fecha solicitada y aprobada es verdadera. ¿ Por qué tiene esto a diferencia del
que está consiguiendo los detalles que tiene mucho más. Por lo que swagger en realidad está mirando a nuestros tipos de retorno en el control particular como más bien nuestras opciones. Y solo saltaré de nuevo al mando para que veas a qué me refiero. Recuerda que voy a decir en que hay un beneficio de poner el tipo de retorno directamente en que realmente me resulta porque saga realmente está usando esto para decir, vale, este es el tipo de datos que se devolverán de esta subasta versus este datatype para esa acción. O fuera de eso, sólo hará una suposición. Y el, el tipo de devolución o el fema que podrías ver
podría no ser representativo de lo que realmente se está devolviendo. Entonces ese es uno de los beneficios que son remotos dijo hay beneficios para poner el tipo de devolución aquí. Esa es una de ellas. Saga inferirá los objetos para los que necesita mostrar el esquema en JSON. Y eso es menos una documentación mejor y más clara para aquellos que estarán interactuando con su API. De acuerdo, así que hagamos una prueba. Saltemos a los tipos de hojas de slash api. Ya que esos han sido sembrados en la base de datos, deberíamos, espero al menos dos registros después de intentarlo contaron. Entonces vamos a golpear ese punto final para probarlo y ejecutarlo. Lo que voy a hacer es establecer un punto de ruptura en el controlador y el manejador que esta operación debería golpear. Entonces cuando ejecuto a 2Ts, el control o la opción más bien, ¿no? Recuerda que es va a mediar un Datsun y símbolo con eso solicita no, estoy presionando F5 y luego va a golpear el siguiente punto de ruptura, que es el manejador. Entonces se ve cuando de controlador a handler y donde realmente está sucediendo
toda la magia dentro del manejador y el manejador, tenemos nuestro repositorio bajo mapeador. Ambos inicializados inyectados. Y luego en el manejador, realizamos la consulta, y luego devolvemos la versión de detalle de los datos. Está bien, así que sólo voy a golpear de nuevo a F5 y permitir que complete su operación. Y luego swagger luego nos muestra los datos que regresan de la base de datos. Ahí vamos, llamado default vacacional es ID1, etcétera, etcétera, etcétera. Y de la misma manera, si voy al get y traté de tote, entonces me permite pasar el DNI. Entonces voy a pasar en ID1, ejecutar, y luego me trae tarjeta The Wanderer con el DNI uno. Ahora el futbol nos permite hacer todas las operaciones crud, al
menos probar alguna vez endpoint que hemos trazado. Entonces probemos otra donde vamos a crear. Por lo que nota la diferencia entre este esquema y el esquema que está siendo devuelto por el detalle vía gets, derecha. Este tiene el ID, el nombre, el valor predeterminado es éste solo tiene nombre en días predeterminados. Eso es porque por supuesto, estamos usando un detalle diferente con alcance limitado. Entonces por el nombre, no
voy a cambiar nada aquí. En realidad sólo voy a poner, dejar estos datos por defecto. Ejecutemos y luego veamos lo que obtenemos. Obtenemos un error 500. Muy bien, ¿por qué llegamos al error 500? Leámoslo de cerca. Entonces recuerda lo que lo pondremos. No cambiamos nada. El nombre habría sido cadena y el predeterminado, estos habrían sido 0. Si recuerdas cuidadosamente, teníamos validación de configuración para ver que el valor predeterminado es nunca debería ser menor de uno. Entonces lo que estamos viendo aquí es un error 500 porque la API, no
sabía cómo manejar el hecho de
que está recibiendo una excepción todo el camino desde el manejador. Y esta excepción es de excepción de validación de tipo. ¿ Eso le parece familiar? ¿ Verdad? Por lo que es sólo hacernos saber que hubo un error y se lanzó esta excepción. No tenemos ningún manejo de excepciones incorporado. Entonces todo lo que se está tirando, swagger no sabe qué hacer es sólo
mostrarnos lo que te dio la aplicación, lo cual está bien. Eso es lo que está diseñado para hacer en este momento. Y vamos a estar refinando eso a medida que avancemos. Pero el punto es que esto está funcionando. Entonces si pongo algo más significativo y esta vez
pondré en licencia por maternidad con días por defecto de 90 ejecutar de nuevo, entonces recuperamos nuestro código de respuesta de 33 sería esa ID. Para que pueda volver al testlet get 3 se ejecute. Ahí vamos. El incumplimiento de la licencia por maternidad es de 90, etcétera. Entonces solo te estoy mostrando lo útil que es swagger para que uno vea el documento para la API y para probar sin tener que instalar ninguna otra aplicación. Ahora que dicho
eso, generalmente uso Postman para hacer mis pruebas de API. Pero para los efectos de este curso, Swagger es perfecto y ha servido a su propósito.
24. Pruebas de unas: descripción de la sección: Sabemos que tendrá un gran portal para aplicación construida. Hemos sacado la mayor parte de lo que necesita estar ahí para la fundación. Hemos configurado la API y la hemos probado hasta cierto punto donde vemos que en realidad se está comunicando con la base de datos y es arte de trabajo. Pero entonces, como hemos visto y hemos discutido más de una vez, las pruebas son una parte muy importante del desarrollo de aplicaciones. Por lo que acabamos de estallar probando la API Andrea para hacerlo manualmente, donde estamos para ponerlo realmente en la herramienta de prueba para la API enviada. Y luego vemos que se sometió y todo. Y entonces estábamos seguros de que nuestro código está funcionando. Pero entonces imagina una obligación mucho mayor con muchos más puntos de contacto. Solo probamos un punto de contacto, solo sepas, pero entonces imagínate probando 50, 60 puntos finales. No tienes el tiempo ni la capacidad para eso. Sería una pérdida de tiempo intentar realmente pasar por todo eso. Es por eso que vamos a estar buscando pruebas unitarias y cómo puede ayudarnos a automatizar esos cheques para asegurarnos de que nuestro código está haciendo lo que lo hemos diseñado para hacer. Ahora en pocas palabras, pruebas
unitarias son código que prueba código. Sí, así es. Vamos a estar escribiendo código para probar nuestro código. Esta es una de las razones por las que la gente rehuye un protón porque algunas personas lo ven como una pérdida de tiempo porque entonces estarías escribiendo código dos veces. Y que algunas personas ven hace completamente esencial porque no
confían en código que no ha sido probado por una prueba unitaria. Hay personas que se suscriben a cualquiera de los extremos. No soy necesariamente uno de ellos. Creo que las herramientas se utilizan dentro del contexto para el
que están diseñadas y en el momento en que estás listo para ellas. Entonces en esta situación, definitivamente
es una herramienta que queremos porque queremos asegurarnos de que nuestros manejadores se estén comportando consistentes con lo que los hemos diseñado para hacer. También queremos escribir lo que llamaremos las pruebas de integración, que solo serán la interrupción entre las diferentes capas de nuestra aplicación. Pruebas unitarias. Una vez más, funciona tan realmente genial en ahorrar tiempo. A la larga. Se tarda un tiempo en escribir las pruebas. Y nuestra prueba sólo es tan buena como cómo está escrita. Pero luego hay marcos por ahí que nos pueden ayudar a asegurar que tenemos pruebas de
calidad y que estamos teniendo cobertura completa para nuestra cotización, otra cosa con la que las pruebas unitarias nos ayudan es la documentación. Para que pudiera dejar documentaciones y comentarios por todo tu código. Pero las pruebas bien escritas en realidad pueden mostrarte nuestro indicarte qué bits de código deberían estar haciendo aquí y allá. Por lo que algunas personas realmente usan las pruebas unitarias como una forma documentar su código de manera extraoficial y de manera. Ahora en general, existen tres tipos principales de pruebas que solemos atender. Uno es pruebas unitarias, el otro es pruebas de integración, cuáles de nuevo, prueba la interacción entre las capas. Y luego pruebas funcionales que suelen ser como UI frente para probar cuál debe ser la experiencia del usuario. Entonces cuando volvamos vamos vamos a mirar a escribir nuestra primera prueba unitaria y
estaremos configurando nuestro proyecto de prueba dentro de carpeta de artistas. Y estaremos probando nuestra lógica de aplicación, también conocido como los manejadores, para asegurarnos de que están haciendo lo que creemos que están haciendo.
25. Prueba de la unidad para el código de la aplicación: Hola chicos. Entonces, comencemos creando un nuevo proyecto de prueba para nuestra capa de aplicación. Por lo que en nuestra carpeta de prueba, en nuestra solución, vamos a crear uno que llamé aplicación de gestión de recursos humanos de mina que prueba unitaria. Por lo que desde un principio, sería nuevo proyecto y estamos buscando una plantilla de proyecto de x unidad. Y entonces queremos darle el nombre por supuesto, y hay que hacerlo a las cinco. De acuerdo, así que una vez que hayas hecho todo eso, entonces puedes saltar a NuGet y queremos instalar MOQ o mock y astutamente. Por lo que Mach nos va a ayudar a crear burlas de nuestra persistencia. Hay repositorios y otros objetos que se necesitan para simular lo que nuestra aplicación o nuestros manejadores están haciendo realmente. Y no debería nos está ayudando a afirmar que esto es lo que esperamos de este tipo de operaciones. Ahora ya me adelanté y configuré una estructura de carpetas para ti. Y creo que les interesan más las cosas para apilables que para que te sientas y me veas tipear. Por lo que he ido adelante y preparado algunos de los activos de antemano, pero como de costumbre, los
pasaremos lentamente y juntos para que podamos entender
por completo lo que está sucediendo en cada uno, en cada paso. En este proyecto, tenemos dos carpetas al menos para no, Así que somos 14 tipos de hojas. Uno para los fumas de Mach será mangueras los repositorios simulados. Ahora tienes dos opciones. Por supuesto que puedes tener un archivo por repositorio simulado, puedes tener un archivo de repositorio simulado y tener múltiples instancias ahí. Eso depende de ti en este momento solo estoy usando un archivo y lo que sólo tendrá una prueba que ejecutar. Entonces si tienes 50 cosas son características que necesitas ejecutar. Nuestros manejadores son características contra las que necesitas ejecutar pruebas unitarias, entonces probablemente sería mejor simplemente dividirlas en archivos
particulares por conjuntos de datos que querrías tener una burla antes. Entonces, entrémonos primero en las burlas. Por lo que ya he pasado por ahí y configuro un método en esto, en este archivo. Entonces vamos a discutirlo juntos. Entonces hice de esto una clase estática pública y estoy llamando a un simulacro de repositorios. Una vez más, fácilmente podría haber sido muy específico y decir algo como mach leave type repositorio. De hecho, voy a tomar mi propia sumisión y simplemente hacerlo de esta manera. Por lo que tenemos este archivo, particularmente para Mach leave type repositorio, el pozo de buck Newcomb de Toronto, repositorio de ubicación de palanca
simulada, etcétera, etcétera. Por lo que Mach leave type repositorio es una clase estática y tiene un método estático en él. Este método está diseñado una vez más pública estática. Y note que está decorado con este simulacro de palabra clave, que nos llega cortesía de la burla de biblioteca, ¿verdad? Y nos permitirá burlarnos de cualquier tipo de repositorio aquí. Entonces quiero un repositorio tipo hoja simulada burlándose del repositorio tipo elif. Y luego estoy llamando al método get leaf type repositorio. Ahora este método va a tener una lista de objetos tipo hoja. Puedes ser completamente ficticio con estos. No hay nada que decir que deben verse como lo que habría en la base de datos. No hay, no hay nada en particular en ello es solo una lista de objetos similares a lo que esperaríamos de la base de datos al tratar con los objetos de tipo de licencia de dominio, ¿verdad? Entonces solo tengo que hacerlo, podrías tener diez, podrías tener 15 o 20 tendría más basado en tu escenario y para lo que necesitas probar. Es posible que necesites más, puede que necesites menos que eso, pero eso depende de ti. Entonces sólo estoy procediendo con dos. Muy bien, entonces inicializamos nuestro simulacro de repo. Entonces voy a decir que grupo ambiental fue igual a nuevo Mock. Y los tipos otra vez es que dejaré repositorio de tipo. Entonces hasta que hagamos todo esto, vas a estar viendo nuestra línea roja al lado de este método porque es decir que no todos los caminos devuelven un valor porque necesitamos devolver el simulacro. Por lo que antes de que podamos devolver el Mach, necesitamos configurarlo. Por lo que los datos de muestra están presentes. Está presente el nuevo objeto del repositorio Mott. Por lo que ahora necesitamos llamar literalmente a simulacro de repo dot setup. Utilizamos una expresión lambda donde nos da acceso a los métodos que habrían estado dentro del repositorio original. Entonces si queremos probar el método get o al menos configurarlo, obtienen todo metódico significa que cuando una prueba está llamando a este repo simulado y queremos invocar una prueba contra código que está usando esto se pone todo. Pasará en el simulacro de repo. Y luego estamos sentados, ellos obtienen todo método. Entonces esta es una cuadra o es una configuración. Nuestra expresión lambda R-dot ghettos L, Eso es todo en un bloque, y luego devuelve la lista de tipos de hojas. Entonces cualquier código que haga nacer la burla va a llamar
al Get off para este repositorio, el simulacro. cual se invocará en la prueba, devolverá esa lista de tipos de hojas. Eso es lo que va a tratar. Está bien, para que puedas, estás en control total de tus datos de muestra. Tienden a T sí para levantarse y empezar con este Misha con los datos de la muestra, pero todo es por una buena causa. No, el siguiente sería configurar lo que sucede cuando llamamos al método add. De acuerdo, así que burla configuración de puntos azules, una vez más ese bloque lambda donde llamamos al método add. Entonces todo eso es una cuadra. Y sólo voy a explicar lo que está pasando aquí. Estamos viendo nuestra normal dot-dot-dot, pero el método add por defecto necesita un objeto de tipo tipo de entidad tipo hoja. Está bien, así que lo dejaré encendido. Muy bien, entonces tenemos que pasar una entidad tipo hoja al método add. Lo que estamos haciendo aquí es que estamos haciendo una especie de aserción que sólo se puede llamar a este método cuando se está pasando un objeto de tipo, tipo de
hoja. Una vez más, este puede ser un objeto ficticio. Simplemente necesita ser de tipo, tipo de hoja. No tiene por qué tener todos estos datos y nada especial. Está bien, así que si está fuera del tipo de hoja, entonces se puede llamar a este método. Y regresa es hundir un objeto. Entonces lo que vamos a hacer es hacer un delegado para decir después de obtener el objeto de tipo hoja, y luego tenemos nuestra expresión o método Lambda bloquearlos, solo muévalo a la siguiente frase para que lo veas más claramente. Entonces decimos tipos de licencia, que es nuestra lista dot add. Entonces durante toda la vida de la prueba, siempre que alguien llame al método add y pase en esos objetos tipo hoja, sólo
vamos a agregarlo a la lista de tipos de hojas y a cambio ese tipo de hoja en particular. Por lo que eso es sólo mantener la configuración funciona y luego basado en el escenario o probar la configuración de Fourier puede diferir. Por lo que te das cuenta de que obtienen toda la configuración se ve bastante diferente de
la, la, lo siento, van a agregar configuración. Y luego el borrar un mil diferente y luego la actualización uno mil diferente. Entonces en este momento sólo estamos sentados o para agregar y conseguir todo. Y luego seguimos adelante y regresamos ese simulacro de repo. Entonces después de devolverla, esa flecha desaparecería, y eso es lo que este método es cuatro. Entonces después de que hayas replicado todo eso, solo
puedes, estoy seguro que estás haciendo una pausa y escribirlo no, pero espero que tengas una mejor comprensión de cómo el MAC nos
ayuda a simular datos sin tocar realmente la base de datos. Ahora saltemos a nuestra primera prueba unitaria. Ahora ésta va a ser consultas, carpetas. He dejado pestañas y comandos y consultas. Muy bien, así que los manejadores que están haciendo consultas serán probados dentro de las consultas se verán y los comandos en los comandos. Entonces el primero que tenemos es el get leaf type list request handler test. Está casi lleno, pero al menos nadie puede cometer un error en cuanto a lo que se está probando. En lugar de este archivo, puedes tener múltiples pruebas por supuesto, pero entonces en este escenario solo queremos tener, solo
necesitamos una prueba realmente para el manejador de listas de invitados o no, déjame solo guiarte por lo que es ocurriendo dentro de estas primeras 10 líneas. Bueno, necesitamos saber que necesitamos auto mapper y sabemos que
necesitamos un repositorio para poder interactuar con el manejador, ¿verdad? Y yo sólo voy a saltar, no he terminado escribir las pruebas de que vamos a hacer eso juntos, pero yo sólo quería demostrar lo que pasa cuando tratamos de instanciar a nuestro manejador, estamos recibiendo un error. ¿ Por qué? Porque un 100 está esperando un parámetro de tipo I elif tipo repositorio y otro parámetro de tipo high mapper. Ahora se trata de una prueba unitaria que no puede simplemente inyectarlas. Eso es 12. No querríamos inyectarlo. Es decir, probablemente podríamos, pero no querríamos porque estamos lidiando con burlas, ¿verdad? No quiero inyectar en el repositorio de tipo elif real porque eso va a hablar con la base de datos. No queremos que nuestra prueba unitaria hable realmente con la base de datos. Sólo queríamos simularlo. Entonces lo que he hecho es inicializar o declarar u otros dos campos privados, uno para el mapeador y otro para nuestro simulacro de repal, ¿verdad? Por lo que privada mach de solo lectura de tipo II elif tipo repositorio gente. Entonces tenemos a nuestro constructor. Entonces en el constructor, una vez que se invoca esta prueba para inicializar nuestro bote burla local para ser igual llamar
al método de repositorio tipo hoja simulada punto obtener método de repositorio tipo hoja. De acuerdo, para que no, haremos toda esa configuración y devolveremos a la gente burlona para usarla en esta prueba. Ahora para el mapeador, una vez más, no estamos inyectando nada. Por lo que necesitamos que este mapeador sepa de todas las configuraciones de mapeo reales que existen en nuestra aplicación. Entonces lo que vamos a hacer es inicializar objeto de configuración mapper. Ser una nueva configuración de mapeador de mercado. Y entonces tenemos una expresión lambda aquí con nuestro bloque de objetos dentro del cual vemos lambda Tolkien dot add profile para el perfil de mapeo. Después de haber configurado el perfil de mapeo y la configuración, entonces podemos saber simplemente pasar que no lo hizo. Por lo que decimos mapper es igual a mapper. Config dot crea un nuevo mapper usando esa configuración. Entonces en general, nuestro mapeador aquí en artista realmente es Es representativo del verdadero mapeador en la aplicación. Entonces todo el método a continuación saber tiene tarea asíncrona pública obtener lista de tipos de licencia. Entonces somos específicos, ¿sabes para qué estamos probando exactamente? Donde pruebas para el método que obtiene la lista de tipos de hojas. Está decorado con este atributo de hecho porque esto es lo que está diciendo la obligación de que se trata de una prueba unitaria. Entonces este es un dicho, Hey, lo que pase aquí tiene que ser un peleado. Cualesquiera que sean las aserciones aquí deben ser pasadas. Si no pasan, entonces esta prueba ha fallado. Ahora vamos realmente a interactuar en los cientos, también lo son las pruebas más bien. Por lo que decimos var handler es igual a nuevo. Y luego estoy instanciando los 100 que deseé la prueba en este método. Observe las líneas rojas porque requiere nuestro simulacro de ondulación o alguna instancia de un repositorio tipo elif. Entonces burla Bull nos da un objeto simulado, pero entonces puedo obtener la cotización real unquote objeto real a través de MLK repo dot object. Siguiente parada, necesitamos a nuestro mapeador. Está bien, eso se ve bien. A continuación queremos realmente probar la llamada al método. Entonces voy a decir que el resultado var es igual al manejador de punto de Handler. Muy bien, porque había manejador tiene ese método llamado handle y requiere un nuevo objeto o requiere los objetos de solicitud. Por lo que necesitamos pasar en un nuevo objeto de la meta. Y sólo voy a quitarme todo esto y usa el inserto, la declaración de uso. Ahí vamos. Para que no tengamos todo ese texto. Y luego después de
eso, también necesita de cancelación. Tolkien, bien, así contra correa en lata o solo puedo pasar en cancelación Tolkien línea punteada. Muy bien, así que este autobús que en en, sin embargo esta derramando rojo e incluyen cualquier referencia faltante. Ahí vamos. Entonces solo estamos viendo llamar a esto. No estamos pasando ningún token de cancelación en. Somos mandones y ese nuevo objeto, así que no necesariamente tenemos que serlo. Entonces Mach es realmente solo para eso, la parte superior. ¿ Está bien? No, podemos ver un resultado. Y si miras el tipo de datos para obtener resultados, oh, bueno, tenemos que esperar esto. Disculpas. Si miras el tipo de datos para obtener resultado, en realidad
es lista. Sí, ahí vamos. Por lo que el tipo de datos para el resultado es una lista de tipo de hoja DTO. Entonces es bastante fácil a las puertas declaraciones y decir: Vale, bueno, si los conos son mayores que uno, entonces esto o algo así, solo para asegurarnos de que volvimos más de uno porque la lista, así que deberíamos recuperar uno o más. Pero entonces al final del día, podemos sentarnos y pensar en todo tipo de escenarios y demás que quizá nos abrumemos. Entonces por eso tenemos el marco debe llevar a ayudarnos. Por lo que puedo decir resultado dotplot. Recuerda que esto realmente se acaba de enumerar las cosas. Es sólo una lista. Pero fue a tipo debería ser de tipo apagado porque quiero asegurarme de que estoy obteniendo el tipo de datos correcto. El tipo de datos que esperamos de nuestro manejador para esta llamada en particular sería la lista. El tipo de datos sería lista de detalle tipo hoja. Entonces por ahora voy a ver y conocer líneas mandarinas. Sólo trabajemos a través de esta parte. Dejar tipo DTO. ¿ Está bien? No, cuando hago eso, hay pura línea Larry porque debería ser de tipo, probablemente nunca habías visto eso antes. Entonces si controlo WC usando en breve, así que ahí es donde no debería ser entra en juego. Nos ayuda con nuestras aseveraciones, con nuestras suposiciones sobre lo que debería suceder. Voy a seguir adelante y poner en la declaración de uso para la DTU también. Pero entonces ese es el punto que seguramente lo haré. Por lo que invocé el manejador, ejecuto un comando o ejecuto una operación, obtuve un resultado. Y entonces estoy viendo que los resultados deben ser de tipo, hoja tipo DTO. Entonces esa es una aseveración ahí. Y vamos a ver qué tenemos Kinsey resultado dot y el
inicio, empezar a escribir En caso de que voy a ver todo lo posible, correcto, todos estos. Nuestras cosas posibles que podemos afirmar o debe ser no, debe estar en rango, debe estar en orden. Todas estas cosas son cosas que puedes comprobar. Por lo que puedo ver debe ser y decir T2 porque sé para mis datos de prueba que el rodaje, oh lo siento. Debe ser más conteo de puntos C. Ahí vamos. Está bien. Por lo que esto debería ser sólo está escondido en cualquier otra propiedad o el objeto en sí. Y le permite obtener la aserción para cualquier escenario que espere. Entonces sepan que ya hemos dicho esa. Déjame escribir al proyecto y decir ejecutar pruebas. Y eso nos dará Spore autista, que luego hará la prueba y nos mostrará qué pasado. Está bien. De tal manera que uno pasado cuatro, si fueran dos. No, sé que puse dos, pero digamos que dije cinco y volver a ejecutar esta prueba. En ninguna parte consiguiendo fracasos. Y si amplío eso sólo un poco, que ve debe dejar aserción debe ser cinco, barco era dos. Entonces eso significa que si algo cambió en mi código y se busca masivamente en, sé que se supone que mi código debe volver a en todo momento, pero luego algo genes. Entonces digamos que no cambié la prueba. Yo sé que también lo es. Correcto. Pero entonces si pongo un artículo de la madre. Muy bien, entonces aquí es donde entra en juego la modificación del código. Y sí, todo esto es estadístico, pero una vez más, sólo estamos hablando de sonares. Entonces la maternidad o si cambio el código que debería haber regresado a uno, siempre
debería volver a 18, introducir algo. No, está regresando tres. Mi unidad prueba con solo ejecutarlo sabrá decirme cuando algo cambie. Por lo tanto, permítanme volver a ejecutar esa prueba unitaria. Y mi aseveración sigue siendo dos, pero luego tres dólares de juego. Entonces justo al bate, sé que hay algún bicho en el manejador con el
que estoy lidiando o porque algo salió mal. Entonces eso es una especie de lo que las pruebas unitarias traen a la mesa. Ahora vamos a crear nuestros crea deja tipo de prueba de manejador de comandos son. Y así en lugar de carpeta de comandos, puedes seguir adelante y configurar ese archivo. Y va a verse bastante similar al tipo get leaf. Tenemos el mismo repositorio de Mach que se está utilizando. Tenemos el mismo procedimiento de inicialización que se está utilizando. Y entonces tenemos prueba, que es la corriente que por supuesto con el hecho y la tarea donde vemos crear tipo hoja. Entonces invocamos al manejador, que es el manejador de comandos crear tipo hoja, cantando Son los objetos según sea necesario, y luego tenemos los resultados. Por lo que nuestro resultado va a venir de nuestro manejador de comidas mango de punto crear comando tipo hoja. Y recuerda que nuestro comando tipo hoja para crear requiere de toda una vida BTO. Entonces eso significa que necesitamos algún objeto aquí para pasar en nulo, tienes dos opciones. Se pueden crear los nuevos criterios de objeto en este manejador y utilizarlos. Pero entonces si tienes múltiples pruebas, solo
puedes crear un objeto de hoja tipo D2 y usarlo para múltiples pruebas. Entonces voy a usar el segundo enfoque donde voy
a tener mi privada de solo lectura deje ese DTO y luego lo inicializaré en el constructor. Algunas personas después de un tiempo, tienen tantos activos siendo inicializados que este constructor crece demasiado grande. Lo que harían es quizá granja ETL a otro método al que llaman como inicial, configuración
inicial o inicializar. Y luego hacen todas estas inicializaciones ahí dentro. Y a veces los activos se comparten en realidad a través de las pruebas. Entonces lo que harían es granjearlo todo a un archivo completamente diferente, como una configuración de punto crass,
derecha Deja configuración de prueba de tipo. Eso sólo irá adelante y devolverá todos los objetos necesarios. Entonces no hay ambas vías, pero estas no son grandes pruebas. Entonces sólo nos quieren poner el concepto bajo nuestros dedos antes de pensar en obstruirlo demasiado, ¿verdad? Por lo que tenemos toda esa configuración y tenemos nuestro detalle tipo hoja que hay que pasar. Entonces oh lo siento, estoy consiguiendo esta zona porque es el crear hoja tipo BTO, disculpas. Entonces déjame solo arreglar ese tipo de datos y entonces deberíamos estar bien para irnos. Y ahí vamos. Está bien, y por supuesto ninguna identificación está en esa. Está bien, así que veamos qué es lo que tenemos que hacer valer en este. Para una, cuando añadimos una nueva herramienta tipo hoja, nuestro simulacro de repo, entonces el cono debería aumentar, ¿verdad? la misma manera cuando agregamos a nuestra base de datos, si hubiera diez, sepa que hay 11. Entonces recuerda en nuestro repo simulado, habíamos configurado el método add que debería tomar cualquier tipode tipo de licencia y debería agregarlo a la lista. Lo que significa que si fuera a llamar a la lista o a sacarme todo de. El repo justo después de una operación add, entonces debería haber un archivo más, luego hay nulo, un registro más y hay en su momento, ¿verdad? Por lo que hay tres nulos. Permítanme primero la actualización de esta aserción en decir tres. Y entonces llamaré al simulacro de repo. Entonces voy a decir tipos de licencia var. Fui a consultar el repositorio para Khomeini. Entonces por supuesto que estamos haciendo el simulacro de repo dot objetos pensados, y entonces solo podemos conseguir el consigue todo. Entonces cuando invocamos todavía, todo lo que sabemos exactamente lo que estamos recibiendo. Estamos consiguiendo esa lista. Entonces puedo hacer mis resultados pensados que deberían ser. Y sabemos que estamos devolviendo los valores de ID. Entonces después de llamar al create Tumblr para tipo de hoja, debería ser de tipo int, correcto, así que esa es nuestra primera aserción. Y entonces también voy a decir que los tipos de hojas punto, punto debe ser. Y voy a asegurarme de que diga cuatro porque
sabemos que estamos empezando con tres nulos después de la llamada, debería ser para. Ahora antes de ejecutar la prueba, sólo
voy a renombrarlo para que parezca un poco más útil, ¿verdad? Por lo tanto, crea, crea pruebas de tipo hoja. Pero lo que entonces puedes tener múltiples pruebas son los humanos crean tipos de
hojas de pruebas para lo que sucede cuando es prueba inválida para lo que sucede cuando es prueba válida para lo que sucede cuando los valores son valor particular y tienes un regla empresarial en su trabajo debe comportarse de esta manera o de esa manera con base en la naturaleza de lo que sea que se esté pasando ahí. Tantos escenarios, no puedo sentarme a pensar en cada escenario, pero solo te estoy dando el marco sobre el que puedes formular tus pruebas. Por lo que esta prueba es, es una aserción de que cada vez que se agrega un tipo de hoja válido, Este es el comportamiento esperado. Entonces voy a saltar de nuevo a nuestro manejador hace para que podamos entender, nuevo el propósito de las pruebas unitarias. Por lo que se requiere probar que obtenemos Buck, Eso es fácil. De acuerdo, sí, tenemos el repositorio MLK donde solo consulta en el repositorio simulado, se supone que
el manejador haga una cosa de
todos modos lo cual se devuelve lo que hay en el repositorio, eso está bien. Pero entonces en una situación en la que tenemos múltiples resultados en nuestro manejador, queremos probar para cada resultado. Y entonces probablemente lo puedas descomponer en la buena prueba y en la prueba de sangre. Eso es a su discreción en lo que quiere asegurarse de que
tenga cobertura para los posibles resultados. Porque si cambian las reglas de negocio, si entra un desarrollador, cambia la declaración if, aunque accidentalmente, entonces uno de los resultados cambiará y se quiere captar eso lo antes posible. Entonces en nuestro comando crear tipo hoja, y recuerda que estamos haciendo algo de validación aquí, ¿verdad? Entonces validamos el tipo de hoja y luego lanzamos una excepción. Cuando no sea válida. Entonces si es válido, pasamos y devolvemos el DNI. Entonces hemos probado eso ya es. Y vemos donde agregar la cosa realmente trae más registros. Si fuéramos a Git repo. Y eso es bueno, pero necesitamos probar lo que sucede cuando entran datos malos
asegurarnos de que se maneje correctamente de acuerdo a nuestras reglas de negocio. De acuerdo, entonces ahí es donde hicimos las aseveraciones. Afirmamos que si obtengo un objeto de solicitud
inválido con una hoja no válida tipo D DO leave type request DTO leaf ab initio, lo siento, que deberíamos obtener una excepción o deberíamos conseguir ciertas cosas en su respuesta basado en cómo escribiste tu código. Esto es lo que debería pasar. Este escenario es el MIT. Observe también que porque estamos en, en la unidad dos, CO empieza a ver cuántas referencias sobre cuántas pruebas están pasando para su código. Por lo que siempre puedes saber que estás en el verde o estás en el ámbar o verde o no estás en el verde cuando se trata de pasar las pruebas. Por lo que voy a saltar de nuevo a nuestra prueba y he agregado otra prueba para el tipo de hoja inválida agregado. De acuerdo, entonces tenemos el mismo código donde montamos nuestro manejador, ¿no? Y entonces una vez más eso se está repitiendo. Entonces lo que algunas personas hacen y lo que tiendo a hacer a veces es mover ese código
repitiendo hacia arriba a ser un campo privado e inicializado en el constructor. medida
que crece el archivo de carbón de prueba, es posible que quieras cultivar algunas partes de él porque no queremos
tener que hacer esto cada vez que tengas una prueba, tienes que inicializar. Entonces es el mismo manejador de comandos que vamos a estar usando con un repo simulado de C y el mismo mapeador. Entonces después de sentarme en el simulacro de repo, soy el mapeador. Podemos simplemente inicializar nuestro manejador para obtener esos objetos. Entonces pinta artista, bueno, tenemos una línea menos de la que preocuparnos, ¿verdad? Por lo que solo decimos manejador de subrayado, factura de
fecha y hora, y seguir adelante. Entonces en esta nueva prueba, voy a tomar mi hoja tipo DTO y voy a hacer que sea inválida. Entonces recuerda que lo inicializamos para tener 15 días y ese nombre. Pero entonces sabemos que mientras lo estamos probando, si dejaría tipo alguna vez vino con esto, entonces debería ser inválido, ¿verdad? Entonces, sólo vamos a hacer que sea inválido. Y luego voy a hacer algo un poco diferente. No, Entonces estamos probando una excepción. De acuerdo, así que voy a decir la excepción de validación e x es igual a 0, debería. Por lo que obtenemos una clase estática las llamadas no deben arrojar una excepción de validación de sumidero. Y luego abrimos paréntesis y puedes abrir y cerrar. Y entonces en lugar de eso dices asíncronos delegados Lambda flecha. Ahora vamos a nuestros pesos, la llamada manejadora pasando en los detalles. Por lo que literalmente sólo este nueve que estamos poniendo dentro de eso debería lanzar método asíncrono. Entonces al final de la misma podemos probar para conseguir todos los tipos de hojas. Entonces vamos a entrar en las hojas nos, recuerda que lo hicimos aquí arriba y dijimos que debe saber antes. Entonces después de una operación inválida Aún deben ser tres, ¿verdad? Entonces eso es lo que somos área distinta. Nos estamos asegurando de que esto no llegara a nuestro conjunto de datos de repo simulado. Y entonces también puedo asegurarme de que la excepción no sea nula. Entonces esta es mi forma de asegurarme de que una excepción fuera efectivamente trono. Entonces ahora que he hecho todo eso, y cuando estés probando algunos días conseguirás el feto. Entonces cuando te llenas ya que ya sea porque necesitas refinar la prueba para asegurarte de que estás probando lo correcto o lo estás, has leído la prueba y solo estás interactuando y está fallando porque tu código no está pasando la prueba. Muy bien, Así que dos partes miren hacia fuera. Entonces ahora que he hecho todo eso, sigamos adelante y hagamos un nuevo conjunto de pruebas. Y he estado recibiendo todas las luces verdes por todas partes. Por lo que el tipo de hoja inválida agregó todas las aserciones pasadas, lo
que significa que correctamente no lo agregó al repositorio y arrojó la excepción porque la excepción no era nula y la válida se agregó con éxito. Y entonces por supuesto recuperamos adecuadamente las cosas en la ondulación. Muy bien, para que podamos cerrar ese Explorador de Test, y fueron las garrapatas verdes aquí. Y luego si miramos atrás en nuestro código, lo que estaba viendo campo es no ver pasar. Muy bien, para que puedas ver cuántas pruebas están haciendo referencia a este método de manejador en particular en este comando. Entonces esa es una visión general rápida y sucia de las pruebas unitarias y cómo puede ayudarnos con nuestra cobertura de código. Y cordial, por supuesto, el rojo aunque prueba para tus otros manejadores y explora cómo se pueden probar los diferentes escenarios.
26. Configuración de la proyecto ASP.NET MVC: De acuerdo, entonces estamos configurando nuestro proyecto en este nuevo módulo. Y lo que vamos a estar usando para nuestro proyecto de UI es la ASP.Net Core Web App, MVC. Por lo que nuestra aplicación cliente o UI podría haberse construido fácilmente con cualquier tecnología que sea capaz de consumir una API RESTful. Entonces tenemos nuestra API que ya configuramos. Pero cuando vamos a estar creando este cliente, Podríamos haber usado vista angular, reaccionar o larva o blazer, cualquiera de estos. Pero realmente me voy a apegar al MVC porque es raro que realmente veas a un MVC arriba siendo el consumidor de una API. Normalmente es el todo en uno de todos modos, eso, y el proyecto original ya estaba incorporado MVC. Entonces vamos a mantener esa sensación MVC a ella. No hay problema. Pero entonces la arquitectura subyacente ya ha sido destripada y configurada. Por lo que vamos a seguir adelante y solo puedes buscar MVC. Y recuerda que es un ASP.Net Core Web up, no la aplicación Web ASP.Net. Está bien, así que pegas a continuación, le das el nombre, que, en cuyo caso lo estamos llamando h i dot leave management dot MVC, y estamos usando un proyecto dotnet 5. También puedes habilitar la maquinilla de afeitar a tiempo completada mientras estás aquí. Y luego solo puedes golpear crear. Ahora una vez que eso esté hecho, vas a terminar con este proyecto, que es el patrón de plantilla MVC estándar
para una aplicación MVC estándar para dotnet Core. Verás que se parece mucho a nuestro proyecto API, excepto que tiene algunas carpetas más como vistas y modelos. Will MVC Modelo-View-Controller. Y entonces tenemos el mismo archivo de inicio, el mismo archivo program.cs, la configuración de la aplicación. Todas esas cosas son una especie de Pleas Comunes. Y tenemos la carpeta raíz ww www, que tiene los cuatro estáticos. Entonces si ya estás familiarizado con MVC donde no tienes ningún problema, pero haré todo lo posible para ser lo mejor para ser lo más detallado posible con todos los cambios y el código que hay que escribir y cómo todo se vincula. Entonces, cuando regresemos, veremos cómo podemos empezar a integrar nuestra API en nuestros clientes.
27. Usar NSwag para el código de cliente API: De acuerdo, así que somos buck y artista ser es configurar nuestra aplicación cliente para consumir nuestra API. Por lo que ya creamos nuestra aplicación MVC y tenemos nuestra documentación API en forma del sogar noch. Entonces estaremos usando n swapped para ayudarnos a generar, literalmente genera el código que,
eso nos ayudaría a consumir esta API. Y entre swagger y en swag, verás que en unos pocos clics, en unos minutos, tendremos todo el código, o al menos la mayor parte del código necesario para establecer realmente comunicación entre el cliente y la API. Entonces paso 1, trae tu documentación de Swagger y luego podrás dirigirte al archivo JSON que genera haciendo clic en este enlace, que traerá este archivo JSON, que básicamente está potenciando esta pantalla que estamos viendo aquí. Entonces lo siguiente que quiero que hagas es ir a Google o Bing y encontrar la página de GitHub para n swag studio. Entonces puedes descargar e instalar eso y está bien documentado, pero vamos a estar pasando exactamente lo que necesitas hacer para ponerlo en marcha. Por lo que solo puedes descargarlo e instalarlo. Y una vez que hayas hecho eso, serás recibido con esta hermosa interfaz. Entonces hay pocas cosas que tú también quieres hacer. Empieza con este procedimiento. Número uno, desea asegurarse de que el tiempo de ejecución sea correcto. Entonces por defecto, creo que puede ir a la red Core 21. Estamos usando net cinco, así que solo puedes seguir adelante y cambiar eso. Y entonces la URL de especificación necesita ser la URL al archivo JSON proveniente de swagger. Por lo que solo puedes copiar eso desde el navegador y pegarlo ahí. Haga clic en crear copia local. Y luego ves esa documentación aquí arriba abajo. Ahora con todo eso hecho y solo las notas que en swag esos soporta otros tipos de aplicaciones cliente, es decir TypeScript. Si, si estuvieras usando view o reactor, uno de esos frameworks JavaScript, entonces podrías generar código con la misma facilidad usando y swag para esos tipos de frameworks. No obstante, nos estamos apegando a los clientes de C-sharp, así que solo tomarías eso y obtienes esa nueva pestaña. Y luego hay algunos ajustes aquí. Déjame simplemente desplazarme a la parte superior. Aquí hay algunos ajustes que queremos asegurarnos de que estén en la policía. Número uno, configura el espacio de nombres. Entonces para el espacio de nombres tengo HR dot leave management dot servicios MVC dot. Ese es el espacio de nombres en el que pretendo tener todo el código generado. Hay otras cosas que pueden estar marcadas ya, pero sólo voy a pasar y asegurarme de que configuramos la tarjeta F1. Por lo tanto, utiliza la URL base para la solicitud. Desea asegurarse de que eso está marcado así como genera la propiedad URL base debe definirse en la clase base. ¿ Está bien? Desea asegurarse de que tiene
marcado el cliente HTTP inyectado por un constructor y generar interfaces para las clases de cliente. Desplazándose, creo que la mayoría de estos ya están ahí por defecto. Desea asegurarse de que tiene marcados los tipos de detalles genéricos. Y cerca del final. También queremos asegurarnos entonces llegamos al final en realidad, porque creo que todo lo demás aquí ya se rellenará por defecto. Entonces no voy a pasar demasiado tiempo en cosas que ya están ahí y no no estoy cansado, no absolutamente necesario. Entonces cualquier cosa que esté fuera de punto, solo
se asegurará de que esos estén en su lugar. Puedes dejar todo lo demás. Y luego al final de la misma quieres poner en la ruta del archivo de salida para que solo puedas ir a tu proyecto correctamente llamado el proyecto. Mucho Visual Studio, lo siento, grep, haga clic en un proyecto y vaya a Abrir en Explorer, tome esa URL o esa ruta y pegue aquí, lo que estamos poniendo servicios slash, slash servicio cliente dot CSS. Entonces, después de haber hecho todo eso, puedes seguir adelante y presionar Generar archivos y no debería tardar mucho en generar esos archivos. Y luego cuando eso se haga, puedes saltar a Visual Studio e ir a tu base de servicios y clase de cliente de servicio. Tengo algo más rápido que vamos a discutir más adelante, pero es solo enfocarse en el servidor y el archivo de concesión de servicio. Entonces tenemos este archivo de cliente que se genera y nos da una interfaz y la implementación de la interfaz fuera de caja, ¿verdad? Mucha documentación sobre anotaciones realmente no tiene que preocuparse por demasiadas de esas cosas. Pero al final del día, generó un barco 1700 líneas de código, al
menos en mi libro. Por lo que en función del tamaño de su API, puede obtener más, puede obtener menos. Pero el punto es que todo esto se hizo por
nosotros para que podamos enfocarnos en cosas más importantes, ¿verdad? Por lo que queremos trabajar de manera más inteligente, no más difícil. Y otra cosa importante a tener en cuenta es que dentro de swag, en cualquier momento esa documentación cambia, lo que significa que alguien hizo un cambio a la API, swagger. En consecuencia, consiguió, aunque en los endpoints cambiaron los requisitos, ¿qué cambia eso? Siempre puedes simplemente eliminar en lo que estás metiendo. Y así de nuevo, regenera este archivo para que no
tengas que conseguir que eso reduzca el ida y vuelta, sobre todo en un entorno ágil donde los cambios son inevitables y rápidos. Entonces siempre puedes simplemente mantener el ritmo con regenerar en este cliente y cambiar el código a su alrededor según sea necesario? No, no mencioné que tengo algunos otros archivos y si bien vamos a entrar en los detalles de ellos, sólo te
voy a mostrar. Entonces tengo contratos y los contratos que tengo un archivo de contrato o una interfaz por tipo de endpoint que conozco de interactuar y también un archivo de implementación de servicio para cada contrato avons iniciado para Windows en, pero solo te estoy dando una idea de cuáles
son estos archivos adicionales en el archivo base, carpeta base. También tengo una respuesta API y son más PFAS que van a entrar a la base solo para que podamos tener esa extensibilidad. Pero para no, no tienes que preocuparte por ello. Lo siguiente que tal vez quieras hacer sin embargo, es configurar el soft de Newton. Por lo que probablemente estés obteniendo un error en cualquier lugar que la palabra Newtons de estos siendo referenciada en este archivo. Por lo que siempre puedes ir a New gets. Y luego te gustaría buscar el suave de Newton, lo siento, Microsoft dot ASP, NET Core, VC dot Newton soft JSON. Para que puedas seguir adelante e instalar eso, hacer una nueva construcción, y esas áreas deberían desaparecer. A continuación, en nuestra clase de startups, queremos registrar a nuestro cliente HTTP. Por lo que dices, en los servicios de configuración dirían servicios que agregan cliente. Dirijo PaaS en IE cliente y cliente. Esos dos están sondeando por archivo más generado. Y luego queremos pasarle la dirección base. Entonces es solo un CEO o cliente de uso igualitario, ya
sabes, esa es una expresión lambda. La dirección base de puntos es igual a la nueva URI. Y luego queremos la URL a la API real. Entonces para encontrar esa API de URL, lo que puedes hacer es ir al proyecto de API, expandir propiedades y poner en marcha ajustes. Y luego verías ese puerto SSL. Entonces es básicamente http localhost colon para completo, en mi caso, 44, 3, 27. En tu caso, podría ser diferente, ¿verdad? Por lo que HTTPS localhost y ese puerto SSL como lo ves en tus sentadas de césped. Entonces con eso hecho, en realidad
hemos configurado el cliente o al menos la base para el cliente. Por lo que los contratos y las definiciones de servicio que tenemos aquí y vamos a estar pescando en última instancia
regresan, son relativos a las operaciones específicas que se necesitan por llamada. Porque cuando llamamos a C se pone todo tipo de hojas. ¿ Cómo vamos a mostrar los tipos de hojas en nuestra aplicación? Todavía necesitamos tener modelos. Todavía necesitamos desserializarlo de JSON porque, ya
sabes, API de descanso que están enviando y recibiendo JSON. Por lo que necesitaremos convertir de JSON a algún tipo que nuestra aplicación cliente pueda apreciar. Y entonces podemos permitir que el usuario interactúe con él en consecuencia. Entonces, cuando regresemos, veremos todos esos. Si bien codificando actividades que necesitamos poner en nuestras propias, nuestro cliente.
28. Configurar los clientes de API y el código personalizado y el base: Entonces ahora vamos a estar creando o pasando por algunos de los archivos y
funciones de soporte que vamos a poner en marcha antes de continuar con la construcción de nuestra aplicación cliente. Entonces estas son realmente operaciones de una sola vez por las que vamos a estar
pasando y te explicaré por qué son útiles. No necesariamente necesario, pero al menos útil. Entonces empecemos con nuestras bibliotecas de terceros en nuevos gets. Nos vamos a ir a subir el otoño y vamos a conseguir almacenamiento local por parte de Julian Hansen. Está bien, así que eso nos ayudará más adelante. No necesariamente lo vamos a usar ahora mismo, pero solo puedes seguir adelante y conseguirlo de No, que solo podamos configurar todo de una vez por todas. Estamos consiguiendo tanto altas otoñales como en última instancia extensiones. Y ya tenemos la blanda de Newton. Entonces con todo eso instalado en la startup, vamos a asegurarnos de que agregamos el automapper. Ahora probablemente te estés preguntando, vale, ¿por qué estoy agregando el último papel? Otra vez después probablemente lo hicimos ya en la aplicación. Por lo que habíamos configurado estos servicios para su distribución en nuestra capa de aplicación y habíamos agregado oper otoñal. Entonces probablemente te estés preguntando, bien, igual que con la API cuando acabamos de llamar a configurar aplicación y servicios. ¿ Por qué no configuras aplicaciones y servicios que son Clint? Bueno, la realidad es que el cliente realmente no sabe
nada de otra cosa en este proyecto, ¿verdad? Entonces es su propio proyecto. Imagínese si estuviéramos usando say, una vista o una aplicación Angular, será lo mismo. No habrá, sí, aparte de que no habría abajo hacia arriba, pero el hecho es que no habría referencias de núcleo o infraestructura. Apenas hace referencia a la API, solo sabe que una API debe encontrarse en una dirección, y esa es la suposición que hace. Entonces con eso dicho, es por eso
que no estamos haciendo referencia a ninguna de las otras bibliotecas dentro de esta aplicación MVC cliente. Es independiente y todo lo que hace es alcanzable a un endpoint y esperar un cierto resultado después, que sería la llamada API que hemos configurado aquí. Por lo que estamos sumando la parte superior otoñal individualmente a este proyecto. Y una vez más, eso es porque cuando estamos consiguiendo el DTO con, podríamos tener que masajear bits de datos antes de que
mostráramos al usuario están interactuando con él de cualquier manera, forma o forma. Entonces agregamos automapper, y ya me adelanté y añadí eso. Bueno, no tienes que preocuparte por que esa línea estará pasando por estas tres líneas a detalle en unas pocas. Por lo que sólo tienes que seguir adelante, añadir el otoño superior. Y entonces las siguientes cosas que tenemos que poner en marcha
sería crear un tipo de respuesta personalizado. Por lo que nuestro tipo de respuesta aquí se usaría cuando hablemos con la API y la respuesta de la API, podría ser con la respuesta del comando. Podría ser con la respuesta de comando de RBS, más bien podría ser con los errores de validación, sea lo que sea. No lo sabemos. Recuerda, solo estamos interactuando con una API, así que o bien estamos esperando que
vuelvan cosas buenas o alguna forma de excepción son algún fuego de engendros de mantequilla. No lo sabemos. Por lo que estamos creando nuestro propio tipo de respuesta genérica en el cliente, que será capaz de obtener un mensaje. Será bueno. Me encanta obtener errores de validación en forma de cadena. Sabrá si fue exitoso y recuperaría algunos objetos, objetos. Entonces lo estoy llamando t go, no
sabemos qué podría ser. Podría ser un objeto con el ya sabes, nos devolvieron el objeto en algunos de los crear, podría ser un entero, sería sólo el ID, no lo sabemos. Por supuesto que sería prudente de nuestra parte retroceder y estandarizar todas esas cosas. Para fines educativos, habríamos pasado por diferentes escenarios. Pero al menos entrando en el entorno más empresarial, quisiéramos estandarizar eso para que
definitivamente podamos saber qué esperar para cada escenario. Entonces ese es nuestro material de respuesta del cliente. Está bien, así que pasando en el siguiente el siguiente expediente que tenemos que quiere mirar es que reclamo. Entonces en la carpeta base tenemos un cliente y tú tienes clientes que probablemente estés viendo. Está bien. Pero, ¿no vimos al cliente de AAE y al cliente antes? Y si estás viendo eso, entonces tienes razón. En nuestros clientes de servicio que se generó, sí
tenemos ironclad y sí tenemos cliente. Pero entonces sólo queremos que tipo de crea una pequeña extensión de eso para que no tengamos que cavar demasiado profundamente para llegar a ciertas cosas. Entonces uno, notarías que esto es parcial. ¿ Está bien? Entonces lo genial de un parcial es que significa que puedes tener múltiples versiones de la misma clase. Por supuesto que todos van a trabajar juntos. Pero cualquier kevin tiene múltiples archivos con el mismo nombre, el mismo nombre de clase, o nombre de interfaz. Y es como si todos se fusionaran en tiempo de ejecución. Entonces es bastante guay si nunca has interactuado con parciales. Pero ya tenemos el parcial que se genera para nosotros. Por lo que sólo vamos a crear nuestra propia implementación parcial o nuestra propia Interfaz de Cliente AAE parcial, que sólo tiene acceso al cliente HTTP. Muy bien, entonces en servicio entonces tenemos ese cliente HTTP. Es muy profundo. En tiempos probablemente no muy accesibles, así que solo estamos creando una versión pública de eso. Y luego en la implementación que es público crédito de clase parcial en el, en corte de pelo, lo siento, de Islandia. Simplemente tenemos esa propiedad pública la cual está consiguiendo que regresemos esa propiedad privada de los tipos de servicio. Por lo que ahí está nuestro cliente HTTP privado. Entonces eso significa que esto nos permite no
interactuar realmente con el cliente HTTP en caso de que quisieras hacerle algo. igual que más adelante cuando estamos haciendo seguridad, vamos a querer interrumpir con es para ponerse encabezados antes de que envíe inflamación. Por lo que verás que en unos pocos No 1 a anotar con el cliente y el cliente, quieres asegurarte de que estén en el mismo espacio de nombres que un servicio, gradiente de servicio. Está bien, así que en realidad cuando estaba haciendo esto, no tenía el punto porque le di servicios nbc dot. Ese es el espacio de nombres al que doy en swag para generar este archivo a pesar de que va en la carpeta base. Y luego yo cliente fue creado automáticamente con el espacio de nombres dot ds. Por lo que tienes dos opciones. Podrías ya sea en este a esto, y luego asegurarte de que en swag sepa que el espacio de nombres debería adoptar estos. O simplemente puedes asegurarte de que se trata de servicios porque si no están en el mismo espacio de nombres y no se verán como parciales. Por lo que solo puedes tomar nota de eso cuando lo estás haciendo. Si estás obteniendo algún error que no puedes averiguar por qué los estás consiguiendo. Ahora vamos a volver a nuestra carpeta Contratos. Y ahí dentro verías que tengo un archivo llamado i servicio de almacenamiento local. No. Hablaré de seguir adelante. Los servicios de almacenamiento local para vamos a estar implementando autenticación usando JSON Web Tokens o JWT para breve saber, después de que un Tolkien haya sido fácil de
aplicar, aplicación aquí siendo una aplicación cliente, necesitamos una forma de almacenarlo entre operaciones, así que inicias sesión y luego mientras estás conectado, probablemente estés mirando tu licencia, probablemente
estés haciendo una serie de cosas. Cualquiera puede estar haciendo cualquier cosa en cualquier momento del sistema. Pero vamos a requerir autenticación para que puedas completar ciertas cosas. Por lo que definitivamente un token necesita estar presente. Como dije, vamos a estar agregando eso más adelante. Pero quiero configurar esto al menos el servicio local ojo, servicio almacenamiento
local desde null porque será necesario para alguna otra configuración bestia que queremos hacer. No. Entonces, después de que obtengas esa biblioteca de almacenamiento local de NuGet, solo
vamos a crear una interfaz donde podamos abstraer algunas de las operaciones en nuestros propios métodos. Por lo que queremos que exista un almacenamiento claro, obtenga valor de almacenamiento y un valor de almacenamiento establecido. Y en realidad es solo un par de claves de valor. Entonces sólo le vamos a dar una clave y un valor. Por lo que puedes usar esto para almacenar pequeños pedacitos de información. Por supuesto, no quieres almacenar nada demasiado sensible dentro del almacenamiento
local porque entonces puede abrir tu aplicación para vulnerabilidades. Pero ese es su propósito. Por lo que después de configurar esta interfaz, puede seguir adelante y configurar la implementación en la carpeta de servicios. Por lo que contamos con servicio de almacenamiento local heredando de mi almacenamiento local. Y tenemos un campo de tipo almacenamiento local que nos llega
de la biblioteca que nos ha dado la red de puntos de Hansen. Y aquí en el constructor simplemente estamos sentados como un poco de config y luego inicializamos el almacenamiento. Por lo que nuestro configure dice nueva configuración de almacenamiento de bajo costo. La carga automática y el autoguardado son verdaderas. Y luego el nombre del archivo le acabo de dar ese nombre que es indicativo de la aplicación a la que pertenece. Para que puedas seguir adelante y hacer eso. Y entonces el almacenamiento es igual a nuevo almacenamiento local. Y todos los métodos son bastante simples. En el almacenamiento más claro, solo
tenemos la lista de claves que queremos despejar del almacenamiento. Por lo que esta coordina a mano cuando alguien probablemente cierre la sesión y quieres eliminar las referencias a los tokens y cualquier otra cosa que hubieras almacenado. Simplemente puedes seguir adelante y pasar en todas las llaves y solo te las quitaría. Tienes el valor de almacenamiento establecido donde pasamos en la clave y cualquier valor y luego lo almacenará. No, Esto es t. Sí, puede tomar como un objeto o una cadena, cualquiera que sea el tipo de datos, pero lo analizará hacia abajo en alguna forma de valor almacenado y luego almacenamiento que persiste el análisis básico, solo manténgalo y asegúrate de que están prestando atención a esto. Obtiene valor de almacenamiento básicamente solo devuelve lo que sea en base a la clave que se solicita. Y entonces siempre podemos comprobar si existe, ¿verdad? Por lo que pasa en la llave y devolverá almacenamiento Xist, que es sólo un booleano. Sí existe o no, no lo hace. No hay un paso que hubiera pasado por alto tours para agregar esto a los archivos de inicio. Por lo que tenemos que decir servicios dot add singleton esta vez porque no necesitamos múltiples instancias de nuestro almacenamiento local. Eso sería en realidad. Bastante mala idea, ¿verdad? lo que solo queremos que persista una instancia del almacenamiento local para todo el usuario, el tiempo de ejecución del usuario o el uso de esta aplicación cliente. Y simplemente estamos pasando en el ojo el servicio de almacenamiento de bajo costo así como el servicio de almacenamiento local? No, En nuestro servicio HTTP base, que está viviendo en la carpeta base en nuestros servicios. Simplemente vamos a estar sentados algunas operaciones de base que queremos que cada servicio pueda hacer. Entonces uno donde tenemos los campos para yo, almacenamiento de bajo costo, servicio de
almacenamiento y un cliente que inicializamos usando nuestro constructor, estamos familiarizados con eso o simplemente inyectándolos. Y luego después, No tenemos dos métodos. Tenemos una en la que convertimos excepciones API son así
que la excepción API viene en realidad de nuestra cogeneración de planta de servicio. Porque al mirar el endpoint, mirar qué esperar, se dio cuenta de que podríamos obtener excepciones de disfraz con código de
estado y respuesta y otras cosas, ¿verdad? Entonces tenemos acceso a ese tipo base, pero entonces probablemente quieras convertirlo en la respuesta si alguna vez llega. Entonces podemos ver si el código de estado de la excepción API es 400, entonces vemos que se han producido errores de validación porque esa fue la mala solicitud, ¿no? Si es 404, entonces vemos mensaje, no se pudo encontrar
el ítem. Y luego de lo contrario, si son 500 y ves que algo salió mal, y tantos códigos de error como
tendríamos b, sabemos que podríamos volver de la API. Siempre podemos configurarlos aquí y tener mensajes personalizados, menos hasta cierto punto, menos hasta cierto punto,
personalizados por tipo de época. Muy bien, El siguiente método sería agregar la cerveza Tolkien. Tan protegido vacío en token portador nos permite ver si el almacenamiento de bajo costo tiene algún valor con la palabra Tolkien. Algunos sólo una vez más,
Linda, Linda creció trabajan aquí, justo donde no estamos del todo listos para este. Sólo lo estoy poniendo ahí y lo discutiremos a detalle más adelante. Pero este método permite agregar el token portador al punto del cliente HTTP, cliente por defecto o solicita autorización, ¿no? Entonces todo este código es básicamente cómo se obtiene acceso a los encabezados de autorización en cualquier comunicación de cliente HTTP con nuestra API RESTful. Y lo que estaremos haciendo es agregar un nuevo valor de encabezado de autenticación. Déjame sólo romper línea aquí sentado o claro. Por lo que estamos agregando un nuevo valor de encabezado de autenticación con el portador de nombre. Y lo estamos poniendo desde el almacenamiento local, obtener valor de almacenamiento de tipo string con esa clave. De acuerdo, así que esa es tu alma estará consiguiendo que los tokens envíen con nuestras solicitudes HTTP. Pero no estamos del todo listos para discutir esto en detalle, pero se puede escribir en el código desde null. Una vez más, todo esto se cultiva trabajo. A nadie vamos a estar mirando nuestro disfraz. No me gusta llamarlos disfraces, pero nuestras extensiones de las diferentes características son los diferentes tipos de interacciones que vamos a estar teniendo con la API por igual, todas las interacciones tipo hoja, todas las solicitudes e interacciones de asignación. Los hemos obstruido en sus propios contratos. Y entonces todos ellos estarán interactuando con el servicio HTTP base de todos modos, porque cuando nos aseguremos, necesitarán cierta funcionalidad de BCE y para una interrupción general. De acuerdo, entonces cuando volvamos y empezamos a mirar a configurar el tipo de hoja, porque esa siempre es la más fácil, ¿verdad? El que es bastante sencillo. Por lo que empieza con esa. Y miraré cómo amarramos todo.
29. Instalación del servicio de gestión de los tipos de permisos: Hola allá, Bienvenido de nuevo. Vamos a empezar a ver los requisitos de servicio tipo hoja. Pero antes de entrar en el contrato y la implementación del servicio en el proyecto de
UI, quiero que hagamos algunas cosas de limpieza con los manejadores y la API. Y voy a explicar, por supuesto a medida que avancemos, por qué estos son beneficiosos antes de seguir adelante. Entonces, para empezar, solo saltemos al manejador de comandos de crear tipo hoja. Y si necesitas nuestra primera escuchada eso está en el proyecto de aplicación en la carpeta núcleo. Muy bien, entonces lo que les animaría a hacer uno es estandarizar lo que se está devolviendo. Por lo que en todos los puntos, queremos probablemente tener la respuesta de comando bs. Recuerda que una respuesta de comando bs nos permite pasar de nuevo la bandera de éxito, el ID del nuevo registro, así
como un mensaje, ¿verdad? Por lo que querrás refactorizar tu código de manejador. Simplemente dejaré esto en la pantalla el tiempo suficiente para que puedas pausar y refactorizar en consecuencia, donde si falla la validación, entonces los éxitos de respuesta caen. Tendrán un mensaje y ponemos todos los errores de validación. Y entonces tenemos más. Si está bien, entonces tenemos el verdadero,
el mensaje y devolvemos el ID con el objeto de respuesta. Por supuesto, si estamos actualizando eso para devolver respuesta de comando bs, eso significa que nuestra solicitud también necesita devolver eso. Por lo que solo puedes seguir adelante y actualizar el comando tipo hoja para tener solicito devolver respuesta de comando bs. Entonces eso son sumas de los cambios que necesitamos en el manejador así como en la clase de comando. Aunque. Pasando de eso, saltemos a la API. Ahora atrás cuando estábamos discutiendo la API, también
mencionamos por qué es una buena idea en los resultados de la acción de tareas incluir también el tipo de datos que se está devolviendo. Y vimos en la documentación de swagger que, ya sabes, para los que tenían nuestro tipo de devolución, la documentación en realidad establecía claramente lo que se devolvería. Ahora que hemos ajustado el tipo de retorno para nuestro manejador de comando create, ajustemos también el tipo de retorno de resultados de acción para el beat con la respuesta del comando bs. Duro porque entonces cuando hacemos eso, obtenemos la respuesta, regresamos bien. Con esa respuesta. Está bien. Para que lo sepamos, realzar nuestra documentación y luego les voy a mostrar otra cosa que la hace aún mejor en cuanto a lo que la documentación
esté actualizada y ser así de explícito nos ayuda a hacer. Ahora una cosa más antes de seguir adelante, quiero que haga clic derecho en su proyecto de prueba y ejecute pruebas. Entonces por si acaso no estabas convencido de por qué las pruebas unitarias son importantes. Si ejecutas las pruebas, probablemente
obtendrás todas las fallas para las pruebas que fueron para comprobar si la,
si la validación o el tipo de hoja válido o tipo de hoja inválida se añadieron con éxito, ¿Por qué fallan? Bueno, acabamos de hacer nuestro refactor, así que simplemente cambiamos algo en nuestro código, nuestro pollo Teslas por una cosa. Y obviamente lo que cambiamos rompería esa prueba. Ahora si vuelves a tu prueba, recuerda que dijimos que el resultado de la operación ADD debe ser de tipo int. Entonces, una vez más, esta es una gran manera de ver dónde refactorizar tu código realmente modificaría las cosas, ¿verdad? Entonces no, la prueba válida habría dicho debería ser de hoja tipo int. Vamos a cambiar eso para que se deba basar la respuesta de comando. Ahora el inválido contaba con que se lanzara una excepción de validación, lo cual era el caso antes o factorizado o nieve. Por lo que realmente necesitamos ajustar esta prueba para saber reflejar que No hay una excepción. Y que solo estamos haciendo el mismo tipo de operación donde solo estamos llamando esperando 0 porque eso es lo que está haciendo nuestro nuevo código, ¿verdad? Entonces estamos llamando a la espera de resultados. Y los resultados deben estar fuera de la respuesta de comando
basada en tipos y el código debe ser de tres. Entonces si volvemos a ejecutar esas pruebas, entonces vemos que tenemos pruebas exitosas todas nuestras propias. Por lo que una vez más, la propia unidad era mantenernos, ayuda a mantenernos en control con nuestros factores y nuestros cambios centrales en un proyecto tan grande. Entonces ahora que hemos modificado o API, necesitamos regenerar la Guerra Fría, el cliente de servicio. Y además de solo regenerarse, hay algunos cambios que quiero señalar con la configuración a medida que lo haces. Entonces una vez más, adelante y consigue ese enlace JSON si no lo tenías levantado ya. Y luego en la interfaz de swag final, lo
vamos a pegar y vamos a recrear la copia local. Entonces tenemos que hacer ese paso cada vez, si lo tuvieras no hay porque lo que vea en el JSON es lo que va a usar cuando está generando el código. Entonces estoy señalando ese dedo porque antes del método post que acabamos de modificar sólo tenía un tipo de retorno de 200, 100 con tal vez un int. No, verás que tiene otros tipos de devoluciones. Está bien. Entonces la inferencia de eso para el final SWACH Studio es que necesita compensar el hecho de que debe esperar nuestro tipo de retorno de respuesta de comando bs. Entonces vamos a ser lo mismo. Entonces si ya lo tienes abierto, está bien. Pero si no, podemos volver a pasar por él. Es administración de licencias R-dot, pero MVC dot services.js, estoy poniendo en la base esta vez Sr. it fuera de la primera vez, quiero asegurarnos de que estamos generando las clases de excepción. Inyectar cliente HTTP vía instructor y generar interfaces para el Acceso de Clientes. Y queremos envolver las excepciones de detalle en el futbol. Instancia de excepción. Queremos generar los detalles. Pero una cosa que si tuvieras antes, me encantaría que desmarcaras Es esto en un barco, la URL base de Estados Unidos para la solicitud. Por lo que inicialmente lo habíamos marcado. Se puede desmarcarlo. Razón al estar en el código de concesión de servicio que
has abierto todo, verías que hay un campo BaseUrl ahí dentro y está esperando una cadena. Por lo que en realidad estamos como de eludir la necesidad de poner la cadena en ese código porque teníamos cliente registrado o HTTP con su dirección base. Entonces no necesitamos eso. Usa BaseUrl para solicitar más. Está bien, para que puedas desmarcar el punto uno y
seguir adelante y asegurarte de que todo lo demás esté marcado en consecuencia. Y una vez que has hecho eso, claro, apuntaste a la ruta de salida y luego generas archivos. Por lo que una vez que ese servicio tendencias CS archivo será regenerado y actualizado para saber esperar ese nuevo tipo de retorno o tipos si refactorías más de una cosas, lo que sea que sea nuevo en tu API
se reflejará en el documentación y como resultado, reflejado en su nueva clase de marca de servicio. Entonces ahora que hemos completado el trabajo de base con nuestros manejadores y nuestra API. Volvamos a nuestra interfaz de usuario. Por lo que estoy en la clase startup y Lee puede ver que
no he comentado la dejo tipo hoja de servicio tipo línea de servicio. Descomentaremos a los demás a su debido tiempo, pero solo puedes empezar con eso en comentado. Y veamos las implementaciones. Antes de eso sin embargo, quiero señalar que sí tenemos el perfil de mapeo. Por lo que creé el perfil de mapeo que sigue los mismos procedimientos que se usaban de nuestra capa de aplicación donde heredamos del perfil cortesía de otoño superior y luego
empezamos a poner en estas configuraciones de mapa de perfil. También he creado algunos modelos de vista. De hecho voy a empezar con el ViewModel antes de ver implementación y
la interfaz del servicio de las hojas. Entonces si simplemente no sabemos dónde a eso, he creado en nuestra carpeta de modelos, deja tipo VM. Acabo de poner todo en un solo archivo esta vez. Entonces en el tipo hoja VM, verás que tengo eso,
que representa la VM que tiene todos los campos, pero solo tiene el ID. Y luego he creado dejar esa VM donde tenemos el nombre y el predeterminado es, así que deja que VM hereda de crear hoja que VM. Por lo que siempre miramos cómo podemos reducir la repetición entre las VMs. Y una vez más, depende de qué tan granular quieras obtener en cuanto a los datos
o los puntos de datos más bien que estés poniendo en tus modelos de vista. Entonces aquí, deja que VM tenga ID y hereda todos los demás campos de Create y crea aquellos que no tienen ese ID. Y ya discutimos es desde el nivel de detalle, por qué eso se hace de esa manera. Por lo que una vez más, desde el perfil de mapeo, puedo mapear like entre el ViewModel nativo del, a la aplicación UI o el camino y el detalle cortesía de nuestro archivo de cliente de servicio AI o archivo de concesión de servicio, lo siento, donde tenemos todos los detalles tipo de hacer referencia en ese expediente. Para que puedas seguir adelante y replicar ese tipo de mapeo y esos modelos. Ahora saltemos a, creo, tipo de servicio. Entonces esta interfaz, está en contratos y básicamente implementa todas las funciones de multitud que sabemos que son nativas. Es necesario que deje las operaciones de tipo se cree que las operaciones de tipo. Entonces tenemos los tipos de hoja get que está devolviendo una lista de lift, IBM, el que obtiene el detalle devolviendo la misma VM. Tenemos respuesta de tarea insular. Miraron la clase de respuesta. Por lo que aquí realmente esperamos esa respuesta relativa al Padre. Estamos obteniendo esa respuesta base del comando que está creando nuestro tipo de hoja. Entonces nuestra tarea va a devolver una respuesta, pero luego interior, esto representa el valor id que está regresando porque eso es lo que realmente estamos, realmente queremos, ¿verdad? Entonces una respuesta relativa al tipo de int crear tipo de hoja y estamos pasando en esa hoja esa VM. También tenemos la tarea de actualizar y una tarea de eliminar. Entonces después de que hayamos configurado todos estos en la interfaz como hemos visto antes, una vez que tengas un contrato, tienes que tener la implementación. Por lo que más en la implementación que acabo de poner en la carpeta de servicios, tenemos el servicio tipo hoja. Entonces pasemos por éste juntos. Entonces esto es heredar del servicio HTTP base por el que pasaron juntos. Y luego dejo tipo servicio en ese punto te va a decir todo lo que necesitas para hacer la implementación. No hay problema, sigue adelante y deja que implemente todos los métodos requeridos. Por lo que dentro de este servicio tipo hoja, tenemos la oleada local, el IM superior y el cliente AAE siendo inyectado. Por lo que todos esos se inyectan e inicializan en consecuencia. También tenemos que pasar a nuestra base. Y base aquí siendo el servicio HTTP base, el cliente HTTP, así como el servicio de almacenamiento local. Ya lo has visto. Entonces hay que poner todas esas cosas. Por favor, apunte a parar ahí realmente para este segmento, cuando
regresemos, veremos los diferentes métodos que se implementaron. Ya tengo algún código ahí, pero eso está bien. Lo revisaremos a detalle en la remontada. Pero estos son tus métodos siendo heredados del servicio tipo elif y están todos puestos ahí esperando ser implementados. Entonces vamos a pasar por eso así como nuestros controladores y nuestros puntos de vista en la siguiente lección.
30. Configuración de la gestión de los tipos de Leave: En esta lección, vamos a estar caminando por nuestros controladores y vistas y la interfaz de usuario general sobre cómo lideramos nuestra aplicación interactúa con la API para todas las operaciones crud. Pero antes de llegar allí, tengo algunas correcciones que necesitamos hacer a nuestra interfaz y la implementación para nuestro servicio tipo hoja. Por lo que las correcciones incluirían actualizar los tipos de devolución para la actualización y eliminar. Yo como que tengo copiando y pegando. Y en la lección anterior, probablemente
habrías copiado sobre las implementaciones incorrectas son prototipos incorrectos para estos métodos. Por lo que puedes seguir adelante y actualizarlos en consecuencia, donde se supone que todos están devolviendo la misma respuesta de tarea relativa al tipo int. Y para la actualización y la actualización delete es bueno tomar un parámetro int id y la hoja tipo VM. Y el delete va a tomar ese parámetro int id. Por lo que puedes seguir adelante y hacer esos cambios y por supuesto actualizar las implementaciones dentro del archivo de servicio tipo hoja. Ahora para empezar a hacer la interfaz de usuario, por supuesto, tenemos que poner la implementación subyacente y luego cablear el código y todo. Por lo que empezaremos con las muy simples, que sería la hoja tipo R para obtener tipos de hojas, que será la lista. Y consiguen detalles tipo hoja, que sería el uno. De acuerdo, así que veamos las implementaciones para esas herramientas. Son bastante simples. Todo lo que estamos haciendo es inicializar una variable que estoy llamando en los tipos de hojas o Napoleón vía tipos de hojas iguales esperan cliente. Entonces este cliente no es la subvención HTTP que se está
inyectando en lo que el cliente viene del servicio HTTP obeso, ¿verdad? supuesto, casi sería lo mismo porque la única razón por la que tenemos ésta es para que podamos pasarla a la base. Está bien, pero apegémonos a ello. Por lo que el cliente de subrayado representa la glándula de servicio HTTP problema base. Y eso es lo que estamos usando. Entonces esperaré en esos Work Trend, tipos de hojas de
puntos, todo un fregadero. Está bien, así que eso nos está dando acceso a todos los métodos que se generaron para nosotros en el servicio cliente thunks the end swap. Entonces verás tipos de hojas de tipos de hojas, los leads se llenan es visto por alguien que lo nombró métodos en tu controlador API, posible
que veas nombres ligeramente diferentes, pero acabo de mirar particularmente convención de nomenclatura para API estándar desarrollo. Y yo sólo estoy consiguiendo estos. Entonces creo que está bastante claro que este está consiguiendo todo el otro es conseguir, solo quiero conseguir, etcétera. De cualquier manera, los parámetros siempre pueden ser tu guía. Por lo que los tipos Vardy es igual para esperar a todos los tipos de hojas. Y luego regresamos trapeador, lista de
trapeadores, tipo de hoja, VM, los tipos de hojas. Muy bien, entonces por eso esto está devolviendo esa lista de hojas tipo VM, porque esto volvería en la lista son zona pública de tipo
hoja DTLs hora simplemente mapeándolos a nuestra máquina virtual tipo hoja local. Entonces ya miramos al mapeador y la configuración para eso. No fuera de eso, por los detalles, lo que estamos haciendo aquí es conseguir sólo uno. Entonces estamos viendo la hoja var para ser z igual a 08. Cliente. Los tipos de hojas se ponen un fregadero y los consigue retoma a nuestro mentor off int id Y entonces igualmente estamos devolviendo una versión simulada para dejar tipo VM de esta hoja. Ahora vayamos a una de las más complicadas. Empecemos con el tipo de hoja de borrar, y eliminaré el tipo de hoja solo necesita el ID. Solo necesita el ID porque el parámetro API cuando necesita el ID. Por lo que estamos haciendo una captura de tendencia en esta situación donde
vamos a ver a un cliente de peso.leer tipos de hojas, eliminar asincrónico pasando en esa ID. Y luego regresaremos una nueva respuesta de tipo int donde el éxito es cierto. Muy bien, Entonces si eso no fue exitoso, entonces por eso atrapamos y luego convertimos o API que tendría nuestra excepción API lugar de que hubiera estado volviendo a la respuesta con la información apropiada. De acuerdo, así que eso es más o menos para la eliminación. Y luego la actualización. En realidad se ve muy similar a eso excepto hacia tomar ID y el tipo de hoja en como tipo de hoja que VM. Entonces voy a hacer un mapeo para convertir eso de hoja a una VM en el tipo de hoja DTO antes de que luego lo enviemos. Y todo el asunto de este tipo de hojas ponen asíncrono. Si pasas el cursor sobre él, verás que se necesita un ID de tipo string, mi extremo generó cadena. Me pareció sorprendente lo que acabo de decir, déjame trabajar con él en lugar de tratar de solucionarlo. El tuyo toma int, entonces eso está bien. No tienes que hacer este id dot a string, pero en mi caso toma string, así que no hay problema, estoy tomando el id int, solo lo
estoy convirtiendo a string. Y también estoy pasando por encima de esa diabetes de hoja. Bueno eso es que me acabo de convertir. Entonces si todo fue exitoso, sólo
regresamos una respuesta con el éxito siendo igual a verdadero. Una vez más, está en un try catch. Por lo que se cogería cualquier excepción. Conoce con el crear te pone en un poco más. Entonces empecé o habrías visto un adelanto de esto. Bueno, déjame guiarte a través de lo que este código está haciendo esta vez. Por lo que una vez más, está devolviendo una respuesta con inmersión en estaca, crear hoja VM como su parámetro. Y realmente son los mismos bits de código, pero solo con unas cuantas tramas y giros más a ella. Entonces aquí estoy viendo crear detalle tipo hoja y estoy haciendo el mapeo. Y luego estoy viendo Consígueme la respuesta del post. Entonces la razón por la que tengo que hacer esto es recordar que actualizamos nuestra llamada API para devolver esta respuesta de comando. A los otros les devuelvo contenido nulo, ¿verdad? Entonces por eso sólo hay tareas. Pero en el caso del create, realidad
estamos recibiendo retroalimentación después de la llamada. Entonces estamos obteniendo una mejor respuesta, que es respuesta de comando bs. Por lo que el cliente de servicio realmente generó este vidrio para que nosotros imitemos la respuesta de comando base que viene de la API. Entonces recuerda que en este punto todavía no sabemos nada sobre AICPA no se interactuaron con la implementación de respuesta base real que hicimos todo el camino arriba en nuestra capa de aplicación. Todo esto se está haciendo aquí mismo en el cliente arriba. Por lo que básicamente la falta de respuesta ayuda a buck después de hacer un intento de post. Y recuerda que eso se opone al intento, aunque sienta que no es necesariamente un fracaso porque podría haber fallado por razones de validación, pero seguiría recibiendo alrededor de 200 respuestas, ¿verdad? Entonces el try catch, y solo para retroceder un poco, el try-catch aquí es realmente que si el cliente de servicio está configurado de una manera que si la respuesta no es un 200, entonces lo ve como una excepción, razón por la cual hacemos esa conversión. Conoce en el caso del, el Crear, podríamos haber obtenido una respuesta 200 con esta respuesta de comando base, pero entonces no es exitosa. Entonces estamos volviendo, bien, http sabia. Pero la operación en sí no tuvo éxito, por lo que el motor nos está diciendo que no tuvo éxito. Escribimos ese motor así que conocimos ese derecho. Pero en el caso de que estés consumiendo una API de terceros en nosotros, en este punto, habrían tenido que dejarte claro que podrías conseguir un 200, pero siempre hay que revisar esta bandera si es verdadera o falsa. Entonces en este caso, si es exitoso, entonces atuenmos nuestra respuesta, esa es nuestra respuesta local de tipo int. Acordamos los datos con el DNI. Recuerda que hablamos de eso, devolviendo el id del disco recién creado, y entonces el éxito es cierto. Por lo que localmente sabemos que nuestro intento de crear fue efectivamente exitoso. De lo contrario, no vamos a conseguir todas las flechas que se habrían empaquetado en esa respuesta de comando base con esas, con los errores de validación. Y luego los estamos poniendo en nuestra respuesta local y amontonándolos. Y entonces estamos devolviendo esa respuesta para que fuera verdadera o falsa o devolver esa respuesta. Y una vez más, sí atrapamos cualquier excepción que se hubiera arrojado. Entonces ahora que tenemos un recorrido todo luchado, se ve como
nuestro código de implementación de servicios. Y por supuesto esto aún está permeado a los cambios en un ambiente ágil. Puedes hacerlo de una manera y en jengibre por el camino porque hay algo más que está bien. Pero por ahora eso es lo que tenemos. Por lo que el siguiente paso sería empezar a crear nuestros controladores. Y el controlador con el que empezamos sería por supuesto para los tipos de hojas. Para que puedas seguir adelante y hacer clic con el botón derecho en controladores, haz clic en Agregar controlador. Y solo voy a hacer un controlador MVC con opciones de redireccionamiento. Adelante y agrégalo, y vamos a estar llamándolo controlador de tipos de hojas. Entonces sepan que el controlador ha sido creado. El primer orden del día sería montar la inyección. Por lo que queremos inyectar nuestro servicio voy a dejar tipo y podemos, por
supuesto, seguir adelante y agregar cualquier referencia que falte. Por lo que dejo tipo de servicio es nulo en nuestro controlador. Empecemos con lo fácil, voy a decir las páginas más fáciles para ponerse en marcha. Cómo podemos empezar con la página de índice. Forma tan fácil de crear la página de índice. Simplemente puede hacer clic derecho, haga clic en Agregar vista. Y queremos elevar su índice de vista. Queremos la plantilla de lista. Y entonces debería ser una lista relativa al tipo, tipo hoja de VM. Para que puedas seguir adelante y añadir eso. Una vez que hayas hecho eso, obtendrás esa vista. Está bien, así que es bonito y sencillo. Y si estás acostumbrado a MVC, entonces esta no es una tarea real para ti. Entonces ya sabes lo que es esto. Y debido a que no estamos usando un EOF,
nuestro objeto de dominio, ciertas cosas que nos encanta cablear dinero, ya sea esta sección donde está pidiendo la clave primaria, así dicen ítem dot ID. Entonces por eso utilizamos la VM tipo hoja, que tiene todos los campos en contraposición al creador, los otros, porque definitivamente necesitamos el ID por este bien y seguimos
adelante y actualizamos esos enlaces para que edite los detalles y la eliminación. Saber de dónde sacar el DNI cuando necesitemos navegar. Si quieres acariciar la interfaz de usuario desde No, También
puedes eliminar los campos id porque tú y yo sabemos que no necesariamente necesitamos aquellos en las operaciones diarias de mostrar datos. Sepa que se crea la interfaz. Por supuesto, necesitamos dejar que la interfaz N4 de donde está sacando sus datos. Entonces esta convocatoria va a ser bastante sencilla, donde todo lo que vamos a ver es el modelo VAR es igual al peso. El tipo de hoja repositorio git leaf types, que es para lo que acabamos de ver la implementación. Entonces lo está llamando tipos de dejar, lo que luego provoca API y devuelve la versión trapeada. Entonces, una vez más, estamos promoviendo controladores delgados aquí porque querrá estar haciendo toda la lógica aquí, ya
sabes, haciendo la llamada API, haciendo el mapeo, y luego regresar en la vista. Nosotros queremos labrar eso todo a otro lugar. Por lo que el controlador solo sabe, llama a este método, consigue los datos, y luego continúa con la vida. Esta línea roja es porque necesitamos hacer de este método un resultado de opción. Eso es una tarea y un fregadero, ¿verdad? Entonces si quisieras conseguir en realidad solo pasa y haz todos estos porque todos van a estar haciendo llamadas asíncronas. Entonces solo para reducir la probabilidad de obtener estas flechas, solo tienes que seguir adelante y cambiar todo a un resultado AsyncTask of action. Y entonces eso es todo para el índice. Entonces tomemos esto peor sido antes de que lo haga, déjame ir al layout y añadir una URL para ello. Entonces solo estoy agregando un nuevo elemento de menú que dice que es B dash controller tipos de hojas es la acción es índice y es tipos def. Entonces corremos y veamos. Lo siento, antes de que corras, antes de que corras, no
mencioné que necesitamos dejar que tanto el cliente como la flecha API y simultáneamente. Entonces, lo que necesita hacer es hacer clic derecho en esta solución y vaya a Propiedades. Y luego irías al proyecto de puesta en marcha y lo cambiarías por múltiples proyectos de puesta en marcha. Por lo que necesitamos que la APA tenga inicio. Necesitamos MVC para tener también inicio. Si quieres que empiece con nuestra depuración. Por lo que lleva, necesitas un tiempo más corto para empezar. Secant es ir adelante y dar clic en Inicio. Entonces ahora nuestra aplicación está arriba, está funcionando y todo
lo que tenemos que hacer ahora es saltar para dejar tipos. Y ahí están nuestros datos que vienen directamente de nuestra base de datos. Bueno, no lo sabemos. No nos importa en este punto de donde viene. Simplemente sabemos dónde llamar a una API, pedirle los datos y ella, lo estamos mostrando aquí. Entonces todo está pasando fuera de la caja, ¿verdad? Por supuesto, en el fondo, como desarrolladores de API, conocemos todas las palabras que ponemos con unos manejadores y todo para que sepamos de dónde vienen los datos. Ambos nuestro cliente no lo sabe. Muy bien, así que a continuación queremos poder crear. Por lo que necesitamos crear nuestro rasguño que crea vista. Para ello, una vez más, todo lo que tenemos que hacer es ir a Ver, clic derecho Agregar vista, vista de navaja. Y luego queremos crear plantillas. Y el modelo aquí sería el Create leave type VM, y luego seguís adelante y agregas eso. Entonces una vez que hayas agregado la vista y obtienes
el archivo físico, el código que necesitamos escribir aquí es doble. Entonces uno para el get, no
necesitamos ningún código porque solo estamos cargando el formulario, ¿verdad? Entonces ya es, ya está creada esa forma sabiendo que debe ser relativa a los campos que están aquí. Por lo que tenemos el campo para el nombre del feto para los días por defecto. No necesitamos hacer nada más. Entonces, a menos que tengas algo especial, eso está bien. Pero en el nivel básico, no se requiere nada más. No obstante, en post, ahí es donde necesita que ocurra la magia. Entonces lo que tenemos que hacer ahora es a nuestro peso, nuestro llamado a la operación tipo hoja. Y bueno, antes de llegar hasta allí, necesitamos asegurarnos de que estamos mirando el tipo de datos correcto, ¿verdad? Entonces voy a llamar a esto crear hoja a VM y dejar tipo. Adelante e incluye cualquier referencia que falte. Por lo tanto, crea hoja a tipo de hoja VM. Vamos a tratar de obtener una respuesta de la hoja que punto repositorio crear tipo hoja. Y luego si nuestra operación es exitosa, entonces podemos redirigir al índice. Está bien, así que mira este nulo. Si hacemos esta convocatoria, Si fue un éxito, entonces podemos operar como si fuera un éxito. ¿ Qué pasa cuando falló? Entonces, cuando falla, quisiéramos, por supuesto,
agregar nuestros errores de validación a la interfaz de usuario. Por lo que las flechas habrían vuelto con la respuesta. Por lo que se puede decir estados modelo, error de
modelo, errores de validación de respuesta. Y al final de todo esto, acabamos de devolver la vista. Entonces vamos a modificarlo un catch para no devolver la vista tiene un hecho mago Voy a modificar la captura, la captura una excepción real, y entonces podemos agregar esa excepción. Entonces esto es a su discreción. Por supuesto, esto depende de la experiencia que desee que tenga su usuario, porque puede que no necesariamente desee que vea los detalles de esta excepción. Probablemente podrías simplemente poner algo que diga que algo salió mal, por favor contacta a tu administrador. Pero al final de esta operación, sí se
quiere devolver la vista. E incluso puedes volver a poner los datos del tipo de hoja que acabamos de enviar. A la vista para que tenga lo que mostrar al usuario. Entonces tomemos ese para un spin art para que podamos ejecutar la aplicación, saltar a nuestro Create. Y voy a crear compasivamente con el número predeterminado de estos Sten. Bueno, digamos que cometí un error y pongo demasiados ceros. Y luego hago clic en Crear. Aquí verás que estamos recuperando nuestro mensaje de validación. Y estoy seguro de que este mensaje parece muy familiar. No he escrito este mensaje desde que he estado construyendo esta interfaz de usuario. Esto viene directamente de la API. Entonces esto es solo para mostrarte cómo viajó la información desde la API y cómo podríamos ser divididos al usuario que el APIC, Esto es ilegal. Ahora tienes dos opciones cuando se trata de validación. Podrías querer confiar en la API para toda tu validación y tus mensajes y así sucesivamente. Pero entonces lo que pasa es que a ti en alguna API se le cobra por llamada. Muy bien, entonces en esta situación en la que probablemente estés construyendo encima de una API que no
quieres demasiado tráfico o los usuarios de API te dicen que hiciste en demasiado tráfico o tu limitado o algo así. Bueno, se podría hacer es usar la documentación de la API y hacer cumplir la validación desde el lado del cliente. Por lo que este mensaje viene directamente de la API. Seguro. Lo que entonces eso significa que se hizo una llamada API, se hizo
algún proceso, y le disparó a buck con ese mensaje. Todo eso podría haberse evitado si leía la documentación como desarrollador
de aplicaciones cliente y configuraba mis propias reglas de validación desde el lado del cliente. Entonces esto nunca llegaría a la llamada API hasta que esto sea válido por los estándares del cliente. Ahora, hay mics. En base a tu intuición, tendrás que hacerlo de una manera u otra. Pero por ahora, dejamos que la API haga la validación. Y entonces creo que siempre es bueno construir la validación en la API porque esa es la última línea de defensa antes, o al menos en los cientos más bien, esa es la última línea de defensa antes de que consiga la base de datos. Entonces ahí mismo quieres asegurarte de que solo cosas válidas obtengan la base de datos. Podría, sin embargo, animar a sus consumidores API a seguir las reglas de validación. Por lo que la combustión en el número predeterminado de estos 10 con, continúe con la creación y mire eso. Tenemos unos tipos de hojas completamente nuevos, por lo que la creación funcionó y luego una página de índice cargada, recargada y estamos de vuelta aquí. No le importa el DNI. Siguió alguna experimentación. Buck en ambos al menos estamos seguros de que esto está funcionando. Ahora, alguien regresó y dijo compasivamente que en realidad deberían ser 15 días. Y todo lo que necesitamos para seguir adelante y editado. Y todo el primer paso es realmente crear la vista. Por lo que directamente ver en vista editar. Y sabemos que estamos usando la máquina virtual de edición y la hoja tipo. Y luego una vez que tengas todo eso en su lugar, puedes seguir adelante y sumar. Y luego en la edición te das cuenta, igual que con create, tenemos dos métodos. Tenemos el puesto y tenemos los gets, conociendo el Get. Significa que tiene que conseguir lo requerido para ser editado. Bueno, ¿cómo conseguimos ese disco? Ya sabemos cómo obtener una lista de registros. Hemos mirado a conseguir un disco todavía, pero lo que sea genial tenemos el derecho de conseguir el único disco aquí es más o
menos el mismo cool tener que escribir para conseguir el único disco aquí. Entonces lo que vamos a hacer es decir que el modelo var es igual a 08 leaf type repositorio dot get leaf type details. Por lo que los detalles sacarían a la luz todos los campos que se necesitan para una operación de edición. El ID, el, ya sabes, los campos, todos los campos, el nombre de los nombres de los campos están eludiendo a Marino, pero estamos recuperando todos
los detalles para el tipo de hoja que está a punto de ser editado, entonces estamos devolviendo la vista con esos datos. Entonces si bien he hecho este año por las ediciones, realmente sólo
voy a hacerlo de nuevo por los detalles porque es lo mismo. Detalles. Obtenemos los detalles. Llegamos a ID, lo pasamos, y luego regresamos la vista con esos datos. Está bien, así que vamos adelante y hacemos eso, edita para el get. Y luego para el post se va a ver un poco similar a nuestro Crear excepto que nuestros parámetros deben tener el id int y dejar tipo VM. Muy bien, así que ID hoja tipo VM y estaban tratando de obtener una respuesta de nuestro tipo de hoja de actualización. Y luego pasamos en el ID y el objeto a editar. Y si fue exitoso, entonces volvimos al índice. De lo contrario, básicamente simplemente margarita cadena y todo el error de validación, al igual que hicimos con el create. Y luego regresamos la vista con los datos que se presentaron. Entonces empecemos la operación de edición y fuera del autobús se puede ver que hay algunas tarifas que no necesitamos. Por ejemplo, definitivamente no necesitamos mostrar el ID de esta manera, manera aditiva al usuario Eso ni siquiera va a funcionar. O API rechazaría eso por completo. En la base de datos se rechazaría difundir el nombre. Número predeterminado de días. Eso es todo lo que dijimos. Necesitábamos cambiar el 15 y sólo
tengo curiosidad por ver qué exactamente va a pasar si intento esto, si hago clic en Guardar, Muy bien, entonces estoy recibiendo esta señora de valor no puede ser nulo. El valor no puede ser nulo. ¿De acuerdo? Déjame cambiar esto de nuevo a 10 y déjame hacer clic en Guardar. Está bien, así que eso funcionó sin embargo. Permítanme revisar lo que significaba ese mensaje. Si los datos no son válidos. ¿ Recuerdas que nuestro manejador que está lidiando con la actualización, verdad? No, lo fue, o al menos originalmente se diseñó para lanzar la excepción de validación cuando los datos eran inválidos. Entonces saltar de nuevo a ese manejador hace IQ y ver a qué me refería. No devolvimos nada. Fue sólo la unidad o en la que explicamos era sólo algo que decir. Todo está bien. Pero entonces cuando el resultado de la validación no era válido, lanzamos una nueva excepción de validación. Ahora esta excepción de validación no se ha manejado. No hemos escrito ninguna cotización real para manejar lo que sucede cuando nuestro manejador lanza una excepción mantener la API trata con él y cómo todo lo demás baja. Entonces entre el manejador lanzando la excepción, el AICPA y el auto siendo manejo global de errores para saber qué tipo de respuestas en buck. Y entonces el subsidio de servicio no poder comprender qué tipo de respuesta es ésta, entonces estamos recibiendo este tipo de error. Entonces técnicamente, no necesariamente todo lo que no quisieras en absoluto usarlo para ver un error como este. Este es en realidad el error que regresa de ese try catch completo y el mensaje de excepción que se devuelve a la validación del estado del modelo. No necesariamente querrías usarlo para ver eso. Pero más adelante cuando veamos el manejo global de excepciones veremos cómo
podemos mejorar o proporcionar una mejor retroalimentación cuando se
lanzan excepciones a través del manejador o a través de la API todo el camino de regreso a la interfaz de usuario sin que tengamos para compensar demasiados escenarios. Está bien, pero para un todo en realidad vemos que la validación está funcionando hasta cierto punto está fallando porque si pongo un punto de ruptura aquí en este manejador, y luego hago clic en Guardar de nuevo, Oh, tuercas en modo de depuración. O podemos hacer eso más adelante, pero puedes probar eso sí pone un punto de ruptura dentro del manejador. Prueba eso, a ver si verías que golpea la validación no está ahí. Disculpa, la validación es falsa. Y entonces lanzará la excepción buck. Y si pisas y lo sigues por la línea, verás por qué todo esto solo equivale a este mensaje tan vago. No obstante, sí vemos que la edición está funcionando correctamente. Y siguiente parada en. Ya miramos el detalle para que puedas seguir adelante y generar la vista de detalles. Ya tengo el mío, y verás que entre el código que acabamos de poner en el controlador y estás generando la vista, puedes ver los detalles. Por lo que el siguiente sería eliminar. Conoce para la eliminación generalmente almacenada en un paso de dos veces en aplicaciones MVC, ¿verdad? Por lo que normalmente obtienes el registro y se lo muestras al usuario como en una vista de detalles y dices, ¿
estás seguro de que quieres eliminar este registro? Y entonces dirían que sí, y luego básicamente presenta un formulario. Entonces esta es una forma muy segura o la mejor manera de hacerlo. Deja que presente el formulario. Por lo que un puerto lo por la anti falsificación Tolkien y que arrastraría esa operación de borrar. No, lo que haría yo, o hay número de formas de abordar esto. Pero lo que he hecho varias veces es en lugar de usar tanto el bueno como el post, solo
tengo el post, ¿verdad? Entonces así es como se ve mi método de eliminación. Y si lo miras, ves que se parece mucho al, todo lo demás que el editor y el Creador otro. Entonces lo intentamos, obtenemos la respuesta. Si tiene éxito, entonces redirigimos a la página de índice y luego solo estoy devolviendo solicitudes de un byte. Entonces la playa, la aplicación simplemente se sentiría, pero veremos cómo manejarlo más adelante cuando busquemos nulos nuestras modificaciones,
sin embargo, en la página de índice, lo que haría es en lugar de tener este enlace axon, En realidad los envolvería en una granja. Una vez más, hay muchas formas de hacerlo porque algunas personas tienen la forma atravesando y atravesando. Algunas personas tienen un solo formulario y usan JavaScript para verlo cuando haces clic en el botón Eliminar, luego borra la granja. Pero ahora mismo, sólo voy a mantenerlo lo suficientemente simple como para superar esto. Por lo que este es un botón de borrar. Está bien, así que no quería aburrirte con mi mecanografía, así que seguí adelante y terminé la parte superior. Por lo que nuestro formulario se ve algo así, donde forma es Opción, Eliminar es B dash, ID de
ruta es item.name. Usando eso a signo para facilidad de uso. Y método es igual a post. Por lo que entre estos tres sabrá que debe apuntar al método post de nombre axón y pasar en ese ID. Entonces sabe publicar y borrar con esa ID. Y entonces lo que tendríamos que hacer es poner el botón arriba. Entonces botón type submit y le di la clase btn, btn línea discontinua. Por lo que parece que los otros dos eslabones, por lo que parece uniforme. Nadie sabría nunca que es abortar y a menos que realmente entren en el código para ver. Y luego onclick, estamos regresando sobre ventana firme. ¿ Estás seguro de que deseas eliminar? Y luego pasamos en la palabra borrar. Entonces echemos un vistazo a lo que esto representa. Está bien, así que esto es lo que no nos alineamos del todo. Podemos arreglar eso más adelante, pero el punto es que estamos recibiendo ese botón de borrar. Entonces tengo uno muy aleatorio aquí. Creo que alguien intentaba falsear al sistema y entran en eso, así que está bien. Suprémoslo. ¿ Estás seguro de que deseas eliminar este registro? Está bien. Y luego ves que todo pasó. Ese récord ya no está ahí. Por lo que eso significa que nuestra operación de eliminación funcionó con éxito. Y con eso hecho, acabamos de completar multitud para nuestros tipos de hojas a través de nuestra interfaz de usuario. Muy bien, Entonces cuando
regresemos veremos cómo podemos completar
las otras operaciones específicas con las solicitudes de licencia y las asignaciones de licencia.
31. Añade la autenticación de Json web en (JWT) a Json: Hey chicos, bienvenidos de nuevo. En esta lección vamos a estar hablando de autenticación. Ahora el siguiente paso lógico que sigue o configura la interfaz de usuario tipo hoja
habría sido liquidar la asignación de hojas y dejar las IU de solicitud. Pero entonces lo hablado ese plan es que para
destinar licencias o solicitudes de salir necesitamos usuarios o empleados. Entonces la única forma en que podemos conseguir que el empleado vea el sistema es si
han ingresado y sabemos quiénes son, Esa es su esposa. La autenticación tiene que venir antes que esas otras dos características. Entonces como que he ido adelante y lo he implementado porque hay bastante código para escribir y no quiero aburrirte con verme tipear. Entonces claro que voy a pasarlo muy lentamente para que puedas pausar, replicar, y explicar todo lo que hay ahí que hay que entender. No. Fuera de eso, tengo swagger donde he implementado la autenticación JWT, así que solo la tengo arriba para que puedas obtener una vista previa de lo que realmente es la autenticación
JWT en caso de que no estés muy familiarizado con ella. Así que vamos a J, W, y T son cortos de JSON Web Tokens. Y lo que son es como un paquete, sólo una cadena plana que está codificada. Pero dentro de esta cadena codificada están lo que usted llama bits de información son reclamos que permite el acorde D y saber quién es el usuario. Ningún JWT es ampliamente utilizado en la fraternidad API como el estándar para la seguridad porque permite la autenticación sin estado. decir, cuando inicias sesión, realmente no
estás iniciando sesión en una capa API accediendo a la API. Pero si es mucho hueso o protegido y se autentica en la API y
básicamente identifican quién eres y luego envían este token con toda la información sobre quién eres. Por lo que la aplicación cliente ahora necesita ver en cualquier momento que estoy usando la aplicación cliente y solicito datos de la API, necesita incluir este token con
mi información para que cada vez que se llame a la API, cuando ve este token, lo decodificará, verificará que esta persona sea válida y luego podrá ejecutar en la solicitud. Entonces solo una demostración rápida aquí, voy a intentar iniciar sesión. Entonces ya he modificado swagger, ya
he modificado la API con los endpoints de inicio de sesión y registro y vamos a pasar por eso. Pero también he puesto en algunos usuarios de muestra. Y yo sólo voy a seguir adelante y mostrar cómo es el token. Por lo que estoy ejecutando una solicitud de inicio de sesión con uno de mis usuarios. Y ven aquí está devolviendo un 200 con esta respuesta token, ¿verdad? Por lo que obtengo el ID del usuario, el nombre de usuario, el correo electrónico. Y esto es ese JWT o token, ¿verdad? Entonces este es básicamente un vehículo con toda la información que se necesita para identificarme. Entonces solo para mostrarte lo que aparece en este token, voy a saltar a JWT dot IO, que es una herramienta gratuita genial que puedes usar para simplemente pegar tu Tolkien aquí mismo. Es forma codificada y luego a la derecha lo hará esencialmente todo lo que está en este token. Entonces asunto, esa es la dirección de correo electrónico, GTI, que es el identificador JWT. Sí, el correo electrónico, tienes, el ID de usuario, los roles que marca de tiempo de exploración, el emisor, y el público. Para que puedas poner más cosas. Estas son sólo cosas básicas que va a tener este token que estamos generando. Pero en el futuro, puedes poner más cosas y poner toda la información que consideres necesaria para que funcione tu aplicación o tu API. Ahora empecemos en nuestro código art. Entonces en primer lugar, voy a llamar su atención, y sólo voy a derrumbar todo lo que no es absolutamente necesario al, a la conversación en cuestión para que sea menos confuso. Por lo que en nuestro proyecto de aplicación, se
desea agregar una nueva carpeta en la carpeta de modelos llamada identidad. Conoce al agregar esta carpeta que dice que debería haber puesto la configuración de correo electrónico y correo electrónico en una carpeta por sí mismos, pero lo podemos hacer más adelante. Ponlos en una carpeta llamada correo electrónico o correo, algo así. Pero para una identidad de todos los modelos y luego tenemos estos nuevos archivos. Por lo que tenemos solicitud de auth, que básicamente es solo correo electrónico y contraseña. Acabamos de ver que cuando iniciábamos sesión a través de swagger, pusimos el correo electrónico, pusimos la contraseña, y luego la enviamos. Entonces para eso está la solicitud de auth. Respuesta de autenticación es lo que obtuvimos buck a través de swagger, el ID, nombre de usuario, el correo electrónico, y la cadena de token. Muy bien, la configuración de JWT, esto tiene que hacer es similar a la configuración de correo electrónico. Recuerda que queremos la configuración de correo electrónico de la parte del archivo
Up settings.js ON que nos dio todos los ajustes necesarios para el correo electrónico. Bueno, eso es lo que va a pasar con los ajustes de JWT. Entonces vamos a tener un tema clave o una audiencia y una duración en minutos, todo siendo referenciado en el archivo de configuración UP en nuestra API. Ahora igual que todos tenemos la solicitud de auth, vamos a tener la solicitud de registro. Tan a menudo es abreviado de autenticación, simplemente la acorté,
pero puedes ser explícito y decir autenticación. Pero la solicitud de registro va a requerir el FirstName, el Apellido, la dirección de correo electrónico, el nombre de usuario, así como la contraseña. Por lo que cualquiera que se esté registrando al alza y el nuevo empleado que está entrando a la empresa se lo dirá, todavía
puedes revolver más. Es necesario proporcionar esta información. Y entonces la respuesta de redistribución es realmente sólo va a empujar hacia atrás con el ID de usuario. Por lo que después de que esta persona se haya registrado ahí en el sistema, solo
enviamos el ID de usuario. Eso es todo lo que se requiere. No, fuera de eso, también
queremos una nueva carpeta en nuestra carpeta Contratos, y yo lo llamo identidad. Y queremos servicio de autenticación. Por lo que vamos a tener un nuevo servicio donde tengamos inicio de sesión de respuesta de autor de tarea. Y toma esa solicitud objeto de solicitud de auth. Y entonces tenemos uno para distribución lo cual nos está dando la respuesta de registro. Y tiene una búsqueda de redistribución. Y eso es realmente todo lo que se requiere para la aplicación. Para que puedas seguir adelante y revisar si es necesario. Por supuesto, pausa mientras vas para asegurarte de que estás obteniendo todos estos archivos y los campos requeridos. Y note los atributos de validación que están en la solicitud de registro porque queremos
asegurarnos de que estamos cumpliendo con estándares mínimos. Tampoco nuestra siguiente tarea nos tendrá agregando un nuevo proyecto a la carpeta de infraestructura TIC denominada Identity Art. Por lo que el punto de gestión de recursos humanos identifica el nombre, y quisiéramos que éste fuera un punto en él, cinco. Entonces voy a explicar esa. Sí, estamos usando el estándar dotnet para la mayoría de las bibliotecas de clase. Pero en este caso vamos a necesitar ciertas bibliotecas que simplemente no pueden funcionar con una biblioteca estándar dominante. Por lo que queremos dotnet fire para que tengamos 0 problemas de compatibilidad. Y por supuesto esto continuaría en futuras versiones de la misma. Para que puedas seguir adelante y agregar ese nuevo proyecto. Ya lo tengo aquí. Y en este nuevo proyecto, vamos a tener algunas carpetas nuevas. Vamos a tener configuraciones, migraciones, modelos, y servicios. Contamos con nuevos archivos donde tenemos la redistribución de Identity Services. Estamos familiarizados con eso donde estamos sentados de ese expediente de registro para ser llamado desde la API. Y también tenemos nuestro propio contexto DB. Entonces voy a empezar con un contexto DB porque este es probablemente el más fácil. Por lo que en el contexto DB, tenemos identificación de gestión de licencias de clase pública, identidad, contextos DVI heredando del contexto DB de identidad. Observe aquí aunque que estamos escribiendo el contexto de la base de datos de identidad. Por lo que podría haber hecho esto, pero tengo una clase especial de anulación para mis usuarios. Por lo que en términos generales, el usuario de identidad no tiene tarifas extras como FirstName y LastName. Por lo que tengo esta clase de usuario de aplicación que he creado en la carpeta de modelos. Y hereda de identidad usuario. Entonces tiene dos campos. Nombre, Apellido. En tu situación, es posible que necesites que tus usuarios tengan más información sobre esos nombres, apellidos y correo electrónico. Y así tal vez quieras fecha de nacimiento, quieres otros campos. Puedes sumar todos esos aquí mismo. Pero siempre y cuando estés heredando de la aplicación de usuario de identidad, el usuario
se puede usar para reemplazar el usuario de identidad y la operación relacionada con el usuario. Esos te dan acceso a todos los campos necesarios. Por lo que saltando al contexto DB, tenemos el mismo tipo de constructor que
habrías visto desde nuestro contexto DB anterior, donde estamos tomando las opciones de contexto DB y que será Passover vía la API proyecto en el conmocionante una vez más. Y luego tenemos el on model creando. Entonces esta vez no estoy haciendo eso, se pone asamblea. Yo estoy llamando a las abejas sobre la creación de modelos. Y luego los estoy llamando uno por uno. En la practicidad realmente ni siquiera importa. Entonces, sólo sigamos. Por lo que tenemos la configuración de reglas, la configuración del usuario y la configuración del rol del usuario. Entonces aquí es donde estoy sembrando esos bits de datos al generar esta base de datos. Entonces recuerda dije que los usuarios generados antes. Entonces si pasamos a la carpeta de configuraciones, verás la configuración de roles donde tengo configuración reglas heredando de I rol de identidad de configuración tipo entidad. Ahora ésta está configurada para configurar nuevas reglas. Tenemos el ID, el nombre de la regla, y el nombre normalizado ID. Esto solo tiene que estar en buen estado para que puedas ir y conseguir nuestro buen Dino al azar, generar uno en línea, está bien. Ahí lo puedes usar. No tienes que usar el mismo. Yo he comprado. Estos necesitan ser buenos. Por lo que nuestras tablas de identidad no usan enteros como sus ID. Después de que termines con los roles, te gustaría cuidar a los usuarios. Entonces usuarios, hay un poco más en ello, pero en realidad es solo un poco más porque hay más que rellenar, pero es prácticamente el mismo concepto, la usuario heredando de
una configuración de tipo de entidad relativa al usuario de la aplicación. Y luego en nuestro método de configuración, tenemos var Hampshire es igual a nueva contraseña Hampshire, relativo
relevante, lo siento al usuario de la aplicación. Por lo que esto se va a usar para hash la contraseña. Por lo que estamos llenando a los usuarios de la aplicación una vez más se pone un bien, le
estamos dando a éste el correo electrónico y correo electrónico y nombre de usuario
normalizados, nombre de usuario no normalizado, todos son iguales. La única diferencia es que las versiones normalizadas tienen todas las tapas. Si estás familiarizado con el usuario de identidad, entonces no lo haré, no quiero aburrirte, pero como ves que estoy llenando todos los campos en consecuencia. Y luego para el hash de contraseña, estoy usando el HobShare para hash de la contraseña null para el primer parámetro. No tenemos que pasar en el usuario de la aplicación. Obviamente no podemos porque solo estamos creando uno. Pero vamos a hash la contraseña, ¿verdad? Por lo que solo estoy usando mi contraseña predeterminada especial que normalmente cumple con los requisitos mínimos para crear a nuestro usuario en identidad. Entonces tenemos esa para el admin y luego tenemos otra para un usuario regular. Entonces después de que tenemos a nuestros dos usuarios bajo dos reglas, tengo usuario o configuración, que es más o menos configuración de tipo entidad en rol de usuario de entidad. Y luego pasas esa mecanografía para una cuerda. Muy importante. Y luego tenemos dos nuevos roles de usuario de identidad. Tenemos el ID de rol al ID de usuario, ID regla al ID de usuario. Entonces esto es ver rol, creo que este es el rol de empleado al usuario que
supuestamente era el empleado y luego el ID de rol al ID de usuario. Entonces porque este tipo de tiene que suceder para que necesitamos la regla necesitamos usar son todos antes de que el usuario o se genere. Entonces creo que por eso acabo de declarar explícitamente las configuraciones como esta. Por lo que no ejecutaría esta carrera que luego ejecutaría eso. Ahora antes de ir más allá, solo quería 0 canciones las bibliotecas que necesitarás en este proyecto solo para que tengas encima tantas líneas rojas. Por lo que queremos asegurarnos de que tenemos una Speed dotnet Core Authentication, JWT portador, queremos una identidad core, Identity Framework, Core Entity Framework, Core dot SQL, las herramientas, las extensiones para las configuraciones Newton dot JSON y system.out.print modelo de ciudad, JWT de Tolkien. Por lo que probablemente ya incluyste algunos de esos porque al
configurar el contexto DB y algunos de los otros archivos, te habría pedido que necesitas ciertas bibliotecas. Entonces si ya tienes eso, está bien, pero esas son las bibliotecas que necesitarás en general. A medida que avanzas, solo puedes incluir los faltantes usando declaraciones y referencias en consecuencia. Entonces vamos a saltar a la implementación de nuestro servicio de Auth. Por lo que tenemos el servicio de autenticación en la carpeta Contratos. Ahora tenemos la implementación. Estamos acostumbrados a la columna vertebral. Muy bien, así que tenemos tres campos son, bueno, empecemos con el constructor y cómo estamos inyectando al gestor de usuarios. Estamos inyectando al gestor de inicio de sesión y buscamos
opciones para la sección denominada configuración JWTs. Por lo que solo puedes seguir adelante y crear esos tres campos. Y luego en nuestras implementaciones tenemos login y registrarnos, y tenemos algunos métodos privados, pero solo pasaremos por ellos uno por uno. Entonces en nuestro inicio de sesión donde tomar la solicitud de auth, por lo que son memorables que esto va a ser llamado desde la API en realidad. Entonces cuando alguien golpea el endpoint de inicio de sesión o cuando golpeo el endpoint de inicio de sesión, solo conoce la API realmente solo llama a este método que luego hizo las comprobaciones y devolvió el arte de respuesta. Entonces tratamos de conseguir al usuario, si el usuario no tiene que existir, lanzamos una nueva excepción, Así que estamos usando excepciones aquí más adelante veremos el manejo adecuado de excepciones, Manejo Global de Excepciones para la API. Pero por ahora solo usaremos las excepciones y refinaremos a medida que avancemos. Entonces si no se encuentra al usuario, lanzamos una excepción, no
pudimos encontrar a ese usuario. Si el usuario es teléfono, está bien. Pero luego tratamos de firmarlos. Si no se podían guardar en, esa es sólo otra excepción. Ahora si pasan todos esos cheques, lo siguiente sería que generáramos su Tolkien. Y ahí es donde entra este método privado, Generar token. Entonces solo voy a saltar a ese método para que puedas ver exactamente de qué se trata todo este asunto de la generación Tolkien. Entonces estaremos devolviendo JWT kit de herramientas de seguridad que viene en la biblioteca para el modelo de identidad JWT de Tolkien, ¿verdad? Para que puedas, como dije, incluir todas las declaraciones de uso una vez que tengas tu spinning apenas. Visual Studio prompt. actualidad se necesita referencia la biblioteca de efectos. Entonces estamos generando el Tolkien o estamos analizando en el usuario de la aplicación que ha sido telefoneado. Muy bien, así que usuario se cayó aquí y fue capaz de iniciar sesión. Entonces estamos pasando por encima de ese usuario. Conoce, obtenemos los reclamos. Por lo que los reclamos se pueden almacenar en la base de datos. Los juegos, una vez más, son bits de información sobre el usuario. Básicamente puedes almacenar cualquier cosa ya que limpio al usuario en un poco de información que necesitas para que tu aplicación se ejecute, puedes agregarlas a los gritos de usuario. Eso está fuera del alcance de este curso, pero solo te estoy dando una idea de lo que realmente es un reclamo. Por lo que está fuera información sobre el usuario en la base de datos. Vamos a conseguirlo rollos. Queremos todas las reglas porque un usuario podría tener múltiples usuarios Rosa podría ser un empleado y un administrador. Al igual que si soy supervisor de lo que podría tener que ser supervisor fondo también un empleado para que pueda aprobar las solicitudes de licencia. A lo mejor lo que también puedo hacer solicitudes de licencia porque ambos tengo razón, Así que los roles pueden tener múltiples roles para nuestro usuario obtiene todas las reglas. Entonces ahora solo vamos a crear una nueva lista de reclamos. Y luego vamos a sumar a la lista de reclamos todas las reglas. Entonces ya ves, solo estamos agregando nuevo reclamo llamado reglas a los roles son en realidad, hay, déjame deshacerme de esta cadena mágica porque
en realidad hay una constante que podemos usar para asegurarnos de que estamos consiguiendo la regla de carrito tipo Nino a evitar errores tipográficos ya discutimos por qué no queremos ninguna, ninguna cuerda mágica, ¿verdad? Por lo que puedo agregar los tipos de reclamo dot roll y los tipos reclamados es solo una constante que tiene diferentes tipos de reclamaciones que se utilizan principalmente en todo. Está bien, así que siempre puedes dar tu propio nombre para limpio, pero luego hay ciertos estándares que siempre puedes
buscar y solo puedes mirar a través y ver cuál es relevante. Pero en este caso, estamos agregando roles. Entonces voy a usar el tipo de reclamo para rollo. Muy bien, entonces voy a construir otro IRI de reclamos donde estoy viendo nucleón es igual a nuestro nuevo reclamo, es JWT registrado nombres reclamados. Por lo que ha reclamado tipos versus reclamos registrados JWT. Por lo que JWT registró reclamos más o menos. Se trata de reclamos específicos de JWT que generalmente se utilizan para aplicaciones en general. Está bien. Entonces esos son estándares DWT directos versus tipos de crema, que no necesariamente está relacionado con JWT, lo que aquellos relacionados con el usuario. Por lo que puedes combinarlos porque todos bajan al mismo tipo de reclamo. Entonces tenemos los roles y estamos agregando nombres limpios registrados DWT. Jabón. El jabón es corto para el tema. ¿ Está bien? Y eso es en términos generales, los usuarios, el nombre de usuario o su correo electrónico, lo que sea único. Ves GTA, que suele ser sólo esa buena cadena, y luego el correo electrónico, que es autoexplicativo. Entonces estoy agregando mi propio reclamo aquí donde llamo al UID o ID de usuario, que es el valor de ID real de la base de datos. Para que veas puedes construir tus reclamos. Puedes poner tantos reclamos, puedes poner en tus nombres personalizados si quieres. Pero incluso, a pesar de que aquí tengo una cuerda mágica, sugeriría que si tienes múltiples afirmaciones personalizadas que necesitas agregar, no agregues las cuerdas mágicas, ponlas en otra constante. Los compañeros de clase es cómo ven aquí las constantes y luego las hacen referencia en consecuencia. Por lo que tendrías tu constante como tipos limpios personalizados, ID de usuario
dot, algo así. Y él QUIEN después de que
construimos esta zona, sólo vamos a puntar unión que el usuario reclama desde la base de datos y el rol reclama, y entonces todo está ahora en este IRI. Entonces bajando un poco más, lo que tenemos que hacer es codificar nuestra clave de firma. Entonces, cuando lleguemos a la configuración de JWT, verás que hay una clave que sería única para tu aplicación. Y hay muchas formas que la gente usa para almacenar la clave en este entorno. Solo vamos a usar settings.js, sun, algunas personas lo almacenan como una variable de entorno. Eso hice en mi último curso de desarrollo de API. Por lo que verás múltiples formas de hacerlo. Entonces todo lo que realmente estamos haciendo aquí es firmarlo. Y lo que querremos hacer también es usarlo para determinar las credenciales de inicio de sesión. Muy bien, entonces entre estas dos líneas, tenemos las credenciales de inicio de sesión. Entonces este bit de ruido de código donde realmente generamos nuestro token de seguridad. Por lo que el token de seguridad JWT es igual al nuevo emisor de token de seguridad. Y eso viene de nuestra audiencia de configuración JWT. Eso también viene de nuestros escenarios y reclamos que acabamos de construir en nosotros mismos, expira. Estamos convirtiendo de fecha y hora saber dónde sumando los minutos que vienen de la configuración de JWT. Una vez más. Y luego estamos agregando las credenciales de inicio de sesión, que acabamos de determinar aquí usando esa clave de firma. Y luego regresamos ese Tolkien. Entonces una vez que regresemos ese Tolkien, vemos mucho cuando se hace en ese método. Después de darle la vuelta a ese Tolkien, entonces construimos nuestra respuesta de autor, que tiene el ID de usuario, el token que acabamos de construir. Y toma nota del acorde aquí, nuevo manejador de tokens de seguridad JWT punto derecho Tolkien y JWT seguridad Tolkien y el correo electrónico y el nombre de usuario, luego devolveremos esa respuesta. Entonces esa fue la respuesta que obtuvimos de swagger con el ID,
el Tolkien, el correo electrónico, y el nombre de usuario. Entonces ahora que hemos hecho todo ese levantamiento pesado entre los servicios y o, ya sabes, todo ese código que sí salta a los Servicios de Identidad o a un archivo de distribución donde configuramos los Servicios de Identidad. Entonces como lo hemos hecho en tiempos anteriores, vamos a necesitar la cobranza del servicio de IA y la configuración yo. Y moviéndose hacia abajo, veremos los diferentes apartados. Por lo que los servicios punto configuran en relación con los ajustes de JWT. Estamos buscando en la configuración para obtener la sección llamada JWT settings. Estamos agregando contextos RDB que estamos familiarizados con eso. Por lo que en realidad podrías simplemente copiar, pegar ese código, solo asegúrate de que estás haciendo referencia al archivo de contexto DB correcto. Entonces es dejar los contextos de base de datos de identidad de gestión, que es el que acabamos de crear para este proyecto en particular. Y estamos agregando SQL Server. Déjenme bajar la cuota. puede ver que es un poco más fácil. Entonces las opciones que usan SQL Server obtienen cadena de conexión, y esto es lo que estoy llamando a la cadena de conexión dejan cadena conexión Identidad de
administración. Ahora lo genial al respecto es que en realidad puedes tener dos data stores completamente diferentes. Si necesita tener un data store para sus aplicaciones separado de un data store para sus usuarios. Entonces esto es, Es así de fácil separarlos porque todo lo que necesitas es una cadena de conexión para una base de datos y otra para otra. Estamos haciendo referencia a la otra cadena de conexión. Entonces en realidad voy a estar separando esos almacenes de datos y lo verás en unos minutos en la configuración de la app. Entonces si deseas usar la misma base de datos para ambos, entonces solo necesitas la misma cadena de conexión. Sin ajetreo. También estamos especificando que el ensamblado de migraciones está en el mismo ensamblado que el contexto DB, razón por la
cual tenemos esa carpeta Migraciones. También contamos con servicios que agregan identidad, donde estamos viendo que la identidad que estamos agregando es usuario de
aplicación para la clase de usuario de identidad y rol de identidad. Estamos agregando el framework, la tienda Entity Framework para ser nuestro contexto DB que acaba de inicializarse arriba. Y estamos agregando proveedores de tokens predeterminados. Por lo que esto agrega los proveedores de tokens usan para generar para restablecer contraseñas G y Gmail, todas esas cosas. Está bien, Así que cualquiera si tienes que hacer esa herramienta, confirmar, e-mail o restablecer contraseña, ese tipo de cosas. Esta biblioteca, te facilitaremos esos proveedores de Tolkien para ti. Estamos en los servicios y estoy agregando éste como transitorio porque queremos un nuevo servicio de auth cada vez que entra una solicitud. Por lo que esta vez no tiene alcance. Me ha dado uno nuevo cada vez. Y sólo somos vinculantes o, o abstracción o implementación. Y luego llegamos a los servicios que agregan autenticación. Por lo que aquí especificamos opciones donde tenemos opciones no por defecto esquema de autenticación es JWT cervecería por defecto esquema de autenticación y esquema Default Challenge es lo mismo. De acuerdo, así es como le decimos al esquema de autenticación que use JWT. Después de eso, estamos agregando las opciones de cerveza JWT donde estoy viendo que los parámetros de validación de Tolkien son como tales. En cursos anteriores donde he pasado por el WTI era de distrito más estrecho, pero una vez más, el contexto determina tu implementación. Entonces para nuestros parámetros de validación de Tolkien, voy a necesitar validar nuestra clave de firma, el emisor, el público, la vida útil, el sesgo del reloj, que obtiene a nuestros sets el reloj al aplicar un tiempo de validación. Entonces relativo a dónde estás, ¿cómo lo aplicamos? Tiempo de validación, validar el EC lo siento, emisor
dividido se encuentra en la configuración para el JWT settings colon emisor. Por lo tanto, esta es una forma rápida y agradable de obtener un valor específico de nuestra sección de configuración en un archivo de configuración de la aplicación. Muy bien, entonces estamos consiguiendo el emisor y el público tanto de la sección de
configuración JWT de la configuración como luego nuestra clave de firma de emisor. Y vimos algo como esto antes donde hacemos la firma de claves de seguridad simétricas para esa clave que también se encuentra en la configuración de JWT bajo la clave de nombre, luego regresamos los servicios. Está bien, eso no, pero ahora que hemos hecho todo eso en nuestra identidad, podemos saberlo, conectarlo con la API. Entonces en la API, voy a empezar con nuestro archivo de configuración de aplicaciones. Por lo que una vez más, tenemos dos cadenas de conexión. Tengo dos cadenas de conexión. Podrías tener uno si quisieras. No hay problema. Pero tengo uno llamado HR leave management DB, que estaban acostumbrados. Entonces agrego 14, la identidad que acabo de anexar en la identidad cuadrada a ella, ¿no? Por lo que realmente no es tan grande de un negocio, dependiendo de las necesidades de tu negocio, es posible que tengas que separarlas. Un caso para cuándo querrías separarlos sería si tenemos múltiples aplicaciones usando la misma tienda de usuarios. Por lo que en esa situación entonces es posible que desee una base de datos independiente estrictamente para información del usuario. Y entonces las diferentes bases de datos son relativas a las diferentes aplicaciones. Pero todas las ops podían suscribirse a la única tienda de usuarios y usar la misma biblioteca de identidades que acabo de configurar y las mismas cadenas de conexión se asentaron. Toda aplicación podría aprovecharla con bastante facilidad. Sería agnóstico a quién realmente está interactuando con él. Entonces tenemos nuestra cadena de conexión y más tarde no en el archivo, tengo la sección de ajustes JWT. Entonces aquí sólo tengo una llave. Una vez más, esta clave podría ser cualquier cosa, podría ser una palabra, podría ser algo así como una contraseña, pero no es algo que quieras que alguien adivine fácilmente
porque entonces la gente podría suplantar a tu Tolkien si conocen tu clave. Entonces por eso dije que a veces la gente no lo almacena en cosas opuestas. Lo almacenan como una variable de entorno o como Application Secret, algo más. Pero por ahora, solo lo estoy poniendo aquí porque es nuestra aplicación, pero ya sabes almacenarla. Más seguridad necesita ser nuestro emisor. Apenas estoy viendo a cada uno nuestra gestión de plomo y el público sería usuario de gestión de licencias de RHH. Y la duración es de 60 minutos, lo que significa que este token es válido exactamente por una hora. Después de una hora, necesitarás un nuevo token, necesitarás volver a iniciar sesión. Entonces es tu discreción que te sientas esta vez. Algunas personas lo pondrían por días, depende de ti y de tu política de seguridad. Ahora saltemos a los controladores de conos en el controlador de colon Estoy inyectando el servicio de auth ojo. Y se puede ver que es un controlador realmente simple. Recuerda, delgado González, Ese es nuestro objetivo, ¿verdad? Entonces, en realidad no hay nada, ni lógica, ni una operación seria ocurriendo aquí. Simplemente estamos implementando a la acción resultados. Uno que devuelve respuesta de autor sobre aunque uno que regrese o una distribución sobre respuesta. Y luego más o menos estamos regresando. De acuerdo, voy a 18 el resultado de la solicitud de inicio de sesión. Una vez más, en nuestro servicio de OSS escolarizado, estamos lanzando excepciones. Por lo que más adelante veremos cómo medimos esas excepciones y tenemos los mensajes de retorno apropiados cuando nuestra aplicación cliente está llamando. Pero por ahora esto es todo lo que necesitamos para iniciar sesión y registrarnos. Y luego en nuestro archivo de inicio, que es el segundo a último bit al que realmente necesitamos prestar atención. Tenemos algunos cambios en consecuencia. Por lo que queremos que configures nuestros servicios de identidad. Y para ello, tendremos que hacer referencia a los proyectos de identidad, ¿no? Por lo que se te pedirá, o
si, si no te piden, entonces al menos agréguelo como dependencia del proyecto cuando tengas la oportunidad, y entonces eso estará disponible para ti. Entonces después de que hayamos configurado nuestros servicios de identidad y otros cambios que quiero señalar es demasiado swagger. Entonces cambié esto a un método que va a configurar el swagger porque son pocas las cosas que van a ser diferentes. Como notan, mi doc de futbol fue ligeramente diferente a las primeras veces que lo usamos. Y por eso. Entonces antes de llegar a este método sin embargo, en el configure para los middlewares, quiere sumar la autenticación de tejidos y se
quiere volver a comprobar que ha utilizado autorizaciones. Por lo que querrás asegurarte de tener esos dos. Si nada más. Dentro de esta configuración, cualquier cosa es que tienes que permanecer sin cambios. Conoce los cambios al doc Swagger, y este es solo el método privado implementado a continuación. Entonces si acabo de derrumbar a estos dos, se ve el muelle de la Liga Árabe Soccer. Se necesita sirvo como colección. Entonces en la llamada de método estamos pasando en los servicios y en este, No, estamos ampliando lo que eran sólo los servicios que tenían futbol, Jen. Entonces no, estamos creando una configuración sobre sangre donde estamos viendo definición de seguridad AD para portador. Entonces esto significa que le estamos diciendo a swagger que cada vez que
se autorice algo y llegaremos a la cotización de autorización unquote parte de la API. Qué, cuando se autoriza un endpoint, entonces requieren un token al portador. Ese es nuestro esquema de seguridad para pruebas que autorizan endpoint requerido. Simplemente le damos esa pequeña descripción en el algun lanzadera verbiage, el usuario, esto es lo que tienes que hacer. Autorización de nombre. En la ubicación perimetral se encuentra el encabezado. Entonces lo que sea que metamos, que es una cerveza, va en el encabezado de la solicitud. Y el tipo es una clave API, y el esquema es un espejo. Está bien, así que esto es tan cortando Swagger. Sepa que si se autoriza un endpoint, una vez más, requieren una cerveza Tolkien, y así es como se debe manejar. Después agregamos los requisitos de seguridad donde vemos nuevas inauguraciones. Una API de referencia de Esquema de Seguridad API
abierta, tipo de referencia Open API es un esquema de seguridad de tipo de referencia llamado esquema portador off to name bear. Entonces verás muchas de las cosas que se están repitiendo. Por lo que sólo tienes que seguir adelante y añadir esa sección. Y entonces tenemos la misma sección doc Swagger donde decimos versión uno. Y el tipo es RHH, gestión de
dejar, EPA y poner un poco de espacio ahí. Está bien. Entonces eso es más o menos. Entonces si iba a autorizar y flotante, así que me viste usar la API. Me viste autenticar, pero no me viste autorizar y probar. Entonces esto es todo lo que realmente necesitas para que la API sepa que debería bloquear todo en este controlador. Si no lo quieres en todo el controlador, puedes ponerlo sobre las acciones específicas. Entonces si conseguir los tipos de hojas no requería que alguien iniciara sesión, entonces eso está bien. No obstante, si crear los tipos de hojas requería que alguien iniciara sesión y luego podrías ponerlo directamente sobre ese post o el PUT, etc. No, casi terminamos con configurar nuestros servicios de identidad. Y en este punto sólo necesitamos dejar que la base de datos
exista realmente y tenerla actualizada con los datos relevantes, ¿verdad? Por lo que voy a ir en la consola Package Manager y asegurarme de que su proyecto de inicio sea la API y que el proyecto predeterminado al que se hace referencia aquí es el proyecto de identidad. Muy bien, entonces el primer comando que necesitas ejecutar es la migración de anuncios para los nuevos contextos de identidad BB. Entonces vamos a decir agregar migración dash. ¿ Cuál tenemos nombre de migración es, pero luego estoy especificando qué contextos esa especificación
podrías obtener un error visto que hay múltiples contextos y no sabe cuál usar. Entonces para conseguir nuestro propio Que sólo digas contexto holandés y el nombre real del contexto. Una vez que hagas eso, obtendrás ese archivo de migración generado. Y tendrás las tablas que se están creando, así
como los nuevos datos que se están sembrando para los roles, los usuarios y
las asignaciones de roles de usuario. ¿ Está bien? Ahora después de que hayas hecho eso, quieres hacer una base de datos de actualización. Por lo que la base de datos va a verse similar en el sentido de que tenemos que especificar qué contextos estamos actualizando. Por lo que solo dices actualizar base de datos dash, contexto
holandés y poner en esa identidad contextos DVI. Y con todo eso no habrías creado la base de datos. Puedo saltar por encima y mostrarles la licencia de RHH Management Identity DB, con todas las tablas que se habrían creado. Una vez más, separé la base de datos de aplicaciones de la tienda de usuarios. Muy bien, entonces vamos a probar esta autorización y luego podemos terminar esta actividad de una vez por todas. Entonces vamos a decir autorizado sobre la lista get u obtener lista de tipos de hojas y punto. Y luego saltaremos a swagger e sesión algunos iniciando sesión como uno del mar que los usuarios tienen el Tolkien. Y luego cuando me desplace todo el camino hacia abajo alguien para probar uno que no está autorizado sólo se pone bien. Entonces veamos el get by ID para poder dividirlo en id1 y ejecutarlo. Y ya ves que estoy recibiendo mi respuesta, no se requiere autenticación. Ahora, si quería probar los tipos de hojas, puede hacer clic en ese candado. Entonces déjame empezar de nuevo. Cuando ese candado me dará las instrucciones que declaramos. Entonces dice, asegúrate de que entras portador luego espacio que tu Tolkien. Entonces esto es lo que realmente parece ir por encima del cable, escribir la palabra espejo. Y ese Tolkien que acabo de copiar de la respuesta del login. Y cuando hago clic en Autorizar, puedo anotar la ropa. Por lo que se refiere al futbol, cualquier solicitud que vaya a estar enviando, al hacer clic en ejecutar, va a incluir ese token portador en el encabezado. Entonces cuando hago clic en Ejecutar en este punto, entonces vemos nuestra respuesta. Entonces déjame intentarlo de nuevo con el barista. Si hago clic en cerrar sesión, borra el encabezado al portador y hago clic en Ejecutar. Y eso lo estoy consiguiendo por una, no
estoy autorizado, no estoy autenticado. ¿ Verdad? Entonces déjame volver a intentarlo. El valor potluck es la palabra portador. Los tolkien autorizan, cierran, ejecutan, y ahí vamos. Por lo que hemos asegurado toda nuestra API, o al menos estamos poniendo la capacidad de tener el EPI asegurado y
de cara al futuro, desde luego ahora podemos replicar ese tipo de política de seguridad a nuestra aplicación cliente.
32. Añade autenticación al proyecto web: Muy bien, Así que estamos saliendo de los talones de hacer alguna API de tienda de modificación pesada con el fin facilitar la autenticación y autorización en cierta medida. Ahora todo lo que necesitamos para replicar esos esfuerzos en nuestra interfaz de usuario donde necesitamos poder permitir que el usuario inicie sesión. Y en base a su papel, deberían poder ver que ciertas cosas no lo son. Entonces aquí estoy iniciando sesión como el usuario administrador y puedes ver he hecho algunas modificaciones al menú donde puedo ver ciertos ítems que no pude antes. Entonces veamos qué se hizo. Una vez más, ya no puedo hacer el trabajo y
te pasaré por él porque no quiero aburrirte con verme tipear. Entonces paso número uno, actualicemos nuestro código generado de swag final porque lo modificamos o API. En consecuencia, nuestra documentación se modificó. Por lo que necesitamos un nuevo conjunto de código para representar el estado actual de la API. Por lo que una vez más, vamos a entrar en swag o runtime se hace a las cinco. Ponemos nuestra URL por delante y creamos una copia local. Y más o menos replicamos todas las configuraciones el mismo espacio de nombres. Nos aseguramos de que todas las, todas las opciones estén marcadas, inyectar, generar la interfaz, y asegurarnos de que estás arriba los detalles y generar los detalles y los tipos de clase. Y cuando todo eso esté hecho, asegúrate de que tu ruta de archivo sea correcta y luego regenera. Sepa, esto es algo que podríamos hacer varias veces en un probablemente debería haberte mostrado esto antes, pero en realidad puedes ir al archivo y simplemente guardar este espacio para
que no te resulte difícil empezar de cero cada vez. Está bien, Así que solo guardaré eso. Y cuando volvamos, siempre podemos simplemente reabrirlo y luego simplemente guardarlo dentro del proyecto. Puedes guardarlo en cualquier lugar. Eso está bien. No obstante, sigamos adelante y continuemos con nuestro código recién generado, que debe saber tener las tareas o el y, o los objetos de solicitud y respuesta para nuestras operaciones de inicio de sesión y registro. Muy bien, entonces ahora que tenemos todo eso, configuremos nuestros servicios de autenticación local. En nuestros contratos, vamos a tener una nueva interfaz, yo servicio de autenticación. Y vamos a tener tres métodos. Uno para autenticar, otro para registrar 12 logotipos. Esto podría haberse llamado fácilmente inicio de sesión, realmente no importa, pero esto es para inicio de sesión, esto es para distribución, y esto se vería obligado a cerrar sesión. Y por supuesto para siempre los contratos, hay una implementación. Entonces en los servicios, tengo esa implementación en forma de servicio de autenticación, que va a heredar del servicio HTTP base así como del contrato. Ahora pasa un poco en este método y te voy
a guiar paso a paso como de costumbre. Entonces, en primer lugar, necesito inyectar mi accessor de contextos HTTP. Y voy a tener un campo privado para JWT security token handler conoce algunas de estas clases y subes. En realidad he visto esta clase desde ni tratando con la API, necesitarás bibliotecas adicionales. Entonces a medida que se te pida instalar las bibliotecas, adelante y haz eso, además de poner las declaraciones de uso. Entonces en nuestro constructor, como hemos visto antes, estoy inyectando los iconos, el almacenamiento local, y yo HTTP context accessor, que se está inicializando aquí. También estamos pasando eso al BCE o al cliente y el almacenamiento a la VCE. Estamos inicializando manuales, por lo que no se inyecten estos manejadores de tokens, pero lo estamos inicializando para que sea una nueva instancia de controlador de token de seguridad JWT. Conoce para las implementaciones porque por supuesto después esta herencia realmente necesitaría la implementación. Para que puedas seguir adelante y generar esos métodos talones y hacernos saber, mirar juntos lo que hay que ir en cada uno. Entonces para el autenticar, tomando contraseña de correo electrónico y tengo todo envuelto en un try catch. Lo que estamos tratando de hacer es generar una solicitud de autenticación. Entonces obtendremos el correo electrónico y el analizador de los parámetros. Y no sé si te he mostrado esto antes, pero en esta carrera, en esta última versión de C sharp, realidad
puedes inicializar un nuevo objeto solo viendo el nombre del objeto del tipo de datos es igual a nuevo, y luego simplemente tener tus valores, ¿verdad? Entonces eso es todo lo que estoy haciendo ahí. Entonces estoy viendo la respuesta de autenticación var es igual a esperar llamada de
los clientes para iniciar sesión asíncrona pasando en esa solicitud de autenticación. Ahora, si el punto de solicitud Tolkien no es igual a string dot empty server sin que el objeto request comprende algunas cosas. Tiene el ID del usuario,
el, creo que la dirección de correo electrónico en otras cosas, dieron
unas cuantas cosas lo único que realmente nos interesa mantener es un token porque eso es todo lo que la aplicación tendrá que usar para ver esto es quién el usuario es. Entonces si el token no está vacío, entonces lo que queremos hacer es conseguir los contenidos de Tolkien. Estoy viendo el contenido var Tolkien es igual al manejador de tokens que se inicializó aquí. Leer JWT, token. Y entonces estamos pasando en la cuerda. Por lo que este es en realidad un tipo fuerte llamado token de seguridad JWT. Muy bien, entonces queremos los reclamos de los Tolkien. Recuerda los bits de información, el correo electrónico, el ID, todo lo que se envió, Bucky, y el token que nos dice quién es este usuario, necesitamos todo eso. Entonces solo voy a analizar las afirmaciones del token. Ahora este es un método que tengo Putin y es aquí abajo donde acaba de devolver la lista de reclamos. Entonces recuerda cuando estamos configurando la herramienta podemos recordar
compilamos la lista de extremidades y la compostamos y la ponemos, codificamos y la ponemos en Tolkien en ninguna parte descodificándola para que conozcamos la lista de reclamos. Entonces en este método, básicamente
estamos diciendo que las afirmaciones var es igual a las afirmaciones de punto de contenido token dos listas. Por lo que todo este objeto de contenido token nos permite simplemente recuperar los reclamos como una lista de cadena o lista de reclamos más bien. Y luego vamos a añadir explícito. El nombre de los tipos de reclamo es Tolkien dot sujetos. Entonces tal vez había alguno, quizá no lo había. Lo estoy haciendo explícitamente. Sólo te estoy mostrando porque tal vez no
sabes lo que estás volviendo a Tolkien a veces. Entonces tú, si quieres ser explícito, siempre
puedes agregar tu propia limpieza con tu propio nombre tal como lo vimos antes. Y pones en cualquier valor que debiera tener. Después de hacer todo eso, devolvemos la lista de reclamos. Muy bien, entonces ahora tenemos los limpios. Necesito crear un usuario para mi actual arriba. Entonces estoy viendo usuarios var iguales al principio de reclamos y sueños principios tendrán una nueva entidad de reclamos Ed con las afirmaciones que acabamos de tomar del Tolkien. Y estamos usando la autenticación de cookies. Entonces una vez que se crea esa persona, estamos almacenando ese registro de usuario o la sesión de ese usuario, la fuente que no hay un usuario actualmente en el sistema como cookie. Entonces veremos cómo se configura eso más adelante en la startup. Pero eso es lo que estamos haciendo. Y luego vamos a hacer un login viendo los accesores de contextos HDTP. Entonces esta es nuestra biblioteca realmente genial en caso de que no estés muy familiarizado con ella, eso te permite acceder realmente al contexto de las solicitudes HTTP. Entonces todo está sucediendo cuando un usuario está solicitando datos o enviando datos, sea lo que
sea que esté haciendo, Todo está sucediendo dentro del contexto de una solicitud HTTP. Por lo que esta biblioteca en realidad utiliza el acceso directo a esa canalización de solicitudes actual y nos permite manipular contextos HTTP y es inyectable por lo que no tenemos que hacerlo desde los controles, puede ser desde cualquier otro lugar. Por lo que puedo decir dame el contexto HTTP en el que estamos y seguir adelante y firmar a este usuario en el uso del esquema de autenticación de cookies. Y vamos a almacenar ese Tolkien en almacenamiento local para su custodia. Entonces recuerda que tenemos el almacenamiento de bajo costo que está siendo llamado por nuestro método token portador cada vez que vamos a hacer una llamada. Entonces por eso tenemos que almacenarlo una vez que lo obtengas, y entonces sólo vamos a volver verdad. Entonces si la persona está autenticada, hacemos todo eso. Vuelvo verdadero. Si regresamos falso, entonces podemos hacer otra cosa. Y eso lo verás en unos minutos. Entonces eso es más o menos lo que está haciendo autenticar. Y si hubo un error en este try-catch, entonces simplemente devuelve falso. Hubo un error, ¿verdad? Entonces eso es autenticar. Y echemos un vistazo al registro, que es mucho más simple realmente. Simplemente vamos a formular esas solicitudes de registro en
base a todos los parámetros que se habrían pasado. Y esto podría haber sido realmente un objeto, pero eso está bien. Se puede referir de nuevo a eso más adelante cuando creemos la solicitud de registro en consecuencia. Y luego pasamos por encima de esa llamada HTTP asincrona registradora con esa solicitud. Y luego si conseguimos ID de usuario de MCI o emisión superficial exitosa, lo contrario, no lo fue. Conoce en nuestro logo, estamos haciendo dos cosas realmente solo estaban despejando el almacenamiento de cualquier valor de Tolkien que hubiera. Y también estamos firmando y destruyendo implícitamente a cualquier usuario. B son las cookies que se crearon durante la firma EC. Eso es más o menos todo lo que está haciendo el cinturón de troncos. Muy bien, así que eso es todo para nuestro servicio de autenticación. No demasiado complicado, ¿verdad? A continuación necesitamos la interfaz de usuario o interfaces que llamaremos a esta alma. Creé a un controlador llamado usuarios Controlador. Y aquí inyectamos I servicio de autenticación y tenemos dos opciones, una para login y 14 login con nuestro post art. Entonces inicia sesión, solo va a devolver una vista y
podemos generar una vista con bastante facilidad con esto. Entonces, bueno, déjame retroceder. En realidad estoy usando el sitio de VM de inicio de sesión, creé una VM de inicio de sesión. Ahí vamos, lo que hace cumplir algunas validaciones son más, pero voy a decir, ya sabes, siempre
podemos hacer cumplir la validación de un cliente dijo que no tengo que depender necesariamente de la API. Entonces algo así como iniciar sesión. No deberías poder intentar iniciar sesión sin que se llene el e-mail Estoy analizador. También tengo un campo llamado URL de retorno. Está bien, así que cada vez que intentes iniciar sesión, vamos a requerir que tengas contraseña de
correo electrónico y ¿dónde también valida los tipos de datos con esos? Y luego en la opción, vamos a generar una vista. Y acabo de decir raise of you login. Yo uso las plantillas de crear porque vamos a estar, necesitamos una granja. Y luego estamos usando la VM de inicio de sesión para esa generación o así después de hacer todo eso, hacemos clic en agregarlos, obtenemos nuestra sencillamente no vista que estamos acostumbrados a ver en nuestra carpeta de usuarios. Y en realidad es solo el formulario de inicio de sesión, ¿verdad? Pongo la URL de retorno como un oculto. Y tenemos un cuadro de texto para nuestra contraseña de correo electrónico 14, cual especifiqué el tipo es contraseña, así que esos son los lazos de caracteres, claro. Y luego el botón dice iniciar sesión, saber cuándo se envía ese formulario, estamos tomando la VM de inicio de sesión y regresar URL. Por lo que la URL de retorno se va ya sea al contenido de salud o a raíz de contenido de URL predeterminada. Y vamos a tener una bandera que diga está conectado, que se va a establecer después de nuestra ponderación una llamada al servicio de auth dot autenticar donde
la política en el login dot email y contraseña de inicio de sesión. Y si obtenemos un booleano, entonces podemos devolver un redireccionamiento a la URL de retorno. ¿Todo bien? De lo contrario vamos a estar agregando un error de estado modelo para decir que el intento de inicio falló estos dragones y acabamos de devolver la vista con el inicio de sesión. Entonces recuerda que una vez que causó esto y esto puede bloquear que vuelve como cierto. Eso significa que ya habrías creado una cookie, ya creado ese registro de usuario o esa sesión de usuario. Y entonces para el momento en que estamos redirigiendo, el usuario habría iniciado sesión. Ahora saltemos a nuestro layout y veamos algunos de los cambios que hicimos. Entonces en nuestro diseño, teníamos nuestros tipos de hojas, enlace o URL justo aquí en esta sección de menú. Entonces lo he quitado y lo he sustituido por este bonito, es un bloque de código. Y también he puesto en este parcial llamado login parcial. Pero echemos un vistazo a un poco de código que he puesto. Entonces en esta UL o lista desordenada donde tenemos todos
nuestros artículos de navegación han puesto en una declaración if que dice si usuario,
por lo que usuario con una U mayúscula por defecto mirar los principios de reclamos, recuerda eso es lo que acabamos de crear en ese servicio de autenticación, ¿verdad? Entonces si esta entidad de usuario dot add está autenticada, entonces queremos hacer esto. Algún usuario.name de pollo está inscrito. Entonces recuerda que enviamos la regla limpia, ¿verdad? Para que podamos ver usuario.email mineral, busca el rol administrador. Y si el usuario está en esa regla, entonces mostramos estos muchos elementos. Por lo que sólo tengo otro elemento de navegación con una clase llamada desplegable y una etiqueta de anclaje que dice Administrar. Y no voy a pasar por cada personaje. Yo sólo voy a desplazarse lo suficientemente despacio para que
puedas ver todo lo que entra en esa etiqueta de anclaje. Está bien. Y luego debajo de eso tenemos un div que tiene los elementos de menú desplegable. Por lo que solo puedes golpear Pausa y replicar eso si es necesario. De acuerdo, así es como conseguimos ese elemento de lista desplegable en el menú. Al menos si estás usando Bootstrap 4, que viene por defecto cuando scuffled o.net predicación de archivos saber en el inicio de sesión parcial, todo lo que hicieron fue crear una nueva vista de afeitar, no usaron ningún modular y los dedos y emptiers de ti lo dieron algún nombre subrayado baja parcial donde generalmente indica que es un parcial de todos modos. Y luego tenemos este bit de código donde tengo otra URL con clase navbar. Y luego dentro de esa declaración avenida, el usuario está autenticado. Entonces queremos un elemento de lista que muestre el nombre de punto de identidad de punto de usuario. Entonces recuerda ese nombre reclamo que dijimos explícitamente. Eso es lo que eso fue arte. Entonces eso es una buena, utilizo una velocidad intermedia en la barra de navegación. Entonces en esa pantalla ahí mismo, y luego tenemos un botón de logotipo. Por lo que el botón Cargar en realidad
es una forma que va a llamar a la acción Logos en el controlador del usuario. Y acabo de incluir esa URL de retorno ahí mismo. Y luego ese botón que dice logotipos. Entonces si el usuario está autenticado, muestra
eso más. Queremos mostrar enlace para una hermana y un enlace para un login. Duele lo suficientemente sencillo. Entonces si no están logueados, queremos que puedan iniciar sesión o registrarse, lo contrario, mostrarles su nombre. Para que puedas seguir adelante y replicar esas líneas. A pesar de que la gran modificación que necesitaba hacerse fue a nuestra startup. Por lo que puedes ver aquí que han pasado bastantes cosas. La última vez que estuvimos aquí. Creo que habríamos tenido hasta este punto. Ahora tenemos todo este procedimiento. Está bien. Entonces, en primer lugar, tenemos que hacerle saber que queremos agregar el accessor de contextos HTTP, es
decir, queremos permitir que sea inyectable en cualquier otra clase, por lo que lo usamos en el servicio de auth ojo. Nos permite a esa instalación. Está bien, entonces quiero configurar las opciones de política de cookies, ¿no? Por lo que los servicios se configuran las opciones de política de cookies no
están en ninguna parte del lado mínimo responsable. Lo sentimos, la vista mínima parece política establecida. Parece que más de uno. Está bien. Por lo que una vez más, esta es una aplicación bastante sencilla. No estoy dispuesto todo con la seguridad, puede
que tengas diferentes necesidades de seguridad, nuestras propias tus cookies y tus políticas. Pero a nivel básico, esto es en lo que estamos sentados. Y luego voy a decir servicios punto agregar autenticación. Y estamos agregando el esquema de autenticación de valores predeterminados de autenticación de cookies. Y solo agregamos galleta. Entonces estoy agregando transitorio o agregando un transitorio o distribución para nuestro servicio de autenticación con su implementación, todo es, sigue siendo prácticamente igual en que los servicios configuran el método de servicios. Pero luego en nuestro Configurar, también
queremos asegurarnos de que agregamos autenticación y que
tenemos ADD o uso de autorización allí también. Por lo que querrás asegurarte de que esas dos líneas sean cárceles. Y antes de seguir adelante, también
queremos asegurarnos de que las políticas de cookies ahí. Entonces las tres cosas en realidad, política de cookies, uso de autenticación y autorización de uso. Ahora, otra cosa que quieres hacer es modificar tus servicios. Entonces sepan que sabemos que tenemos que tener el token al portador adherido a ciertas llamadas de servicio. Ya podemos ir a un servicio. Por lo que tienes el servicio tipo hoja ya en funcionamiento. Y luego podemos llamar al método de token add bearer dentro de cada uno de estos métodos. Entonces justo antes de que realmente nos reunamos con esa llamada de cliente, queremos agregar token al portador. Y así como un refresco en token portador básicamente dice, si el token existe, entonces adelante y agréguelo a la autorización. Está bien, hazlo como una cerveza. Entonces recuerda cuando estamos probando, se jadearía. Cuando tuvimos que probar el endpoint seguro a dónde ir y ver el espacio al portador, el token Eso es todo lo que esto está haciendo es solo ver el encabezado de autenticación valora cerveza. Y estamos agregando ese token. Y la autorización es el encabezado predeterminado, ¿verdad? Entonces ese es el encabezado y está agregando portador. Esto se llama mal. Poner una barrera acelera Tolkien para nosotros. Cuando hacemos eso, lo estamos agregando a ese cliente. Por lo que para cuando el cliente hace la llamada, el token al portador está presente, y entonces todo lo demás puede fluir. Entonces solo puedes seguir adelante y agregar esa ficha al portador porque no sabemos cuándo se asegurará algo no somos ella. No sabemos qué endpoint se asegurará en la API. Bueno, en realidad no importa. El hecho es que sabemos que necesitamos seguridad espejo. Y más que probable, usted sería dueño de su API o una API sería bloqueos no lo hacen completamente a nadie que no esté iniciando sesión está tratando de registrarse. Una vez que hayas iniciado sesión, se espera que tengas tu Tolkien para decir, aquí estoy estos para la información. Ahora como prueba, lo que vamos a hacer es saltar de nuevo a nuestro controlador de tipos de hojas en la API y poner y autorizar sobre todo el controlador, lo que significa que no deberías poder llegar a ninguno de estos endpoints con todo tu token portador, debes obtener un 40 1, lo que significa en autorizado o no autorizado, en autenticado. Más bien, si intentas ir a cualquiera de estos extremos desde la API. ¿ Está bien? Así que recuerda probar, quieres asegurarte de tener en múltiples proyectos,
múltiples proyectos de puesta en marcha, ir a las propiedades de la solución y dejar que comience la API. Estoy empezando con o depurando, digamos que surge más rápido y MVC, también
puedes comenzar sin depurar si no necesitas ir línea por línea. Entonces sigamos adelante y probemos esto. Por lo que tenemos nuestra aplicación MVC, vamos a intentar iniciar sesión. Entonces déjame meterme, pero los intentos. Sé que el usuario no piensa que este inicio de sesión y te da unos cuantos, y luego está rebotando arriba viendo que el intento de inicio de sesión falló. Por favor inténtalo de nuevo. Está bien. Debidamente señalado. Probemos uno que conocemos y luego probarlo de nuevo. Y entonces esta vez ahora estamos registrados sido tan redirigidos
a nuestra página de inicio y no ISI que Manejar elemento de menú, lo que nos da esas opciones porque estamos en como el administrador. Y si voy a dejar tipos, todo carga. ¿Por qué? Porque mi ficha está presente. Sabe que tengo acceso a la información que se solicita. Ah, si me encanta mucho. Y déjame intentar volver a iniciar sesión como el usuario regular, entonces el inicio de sesión va a estar bien, pero no hay gestionar en este momento. Y si este usuario estuviera parado sobre el hombro admin y viera eso para poder llegar a los tipos de hojas y crear mi propio tipo de hoja, puedo hacer esto. Voy a tratar de llegar allí. Se va a ir ahí, ¿verdad? Por lo que alterar rectificar esto. Tenemos algunos puntos de ataque y una vez más, somos opciones. Implementar el que sea mejor para su situación. Pero desde la aplicación del lado del cliente, debemos saber que ciertas cosas están reservadas para los administradores, cosas
inciertas están reservadas para los usuarios o tal vez no libros reservados. Los usuarios no deberían poder acceder a ciertas cosas que los administradores pueden. Por lo que en nuestro controlador de tipos de hojas, probablemente no sea suficiente decir solo autorizar porque esto significa que tienes que estar conectado. También pude ver autorizar con los roles administrador. Por lo que eso significa que solo los administradores deben poder entrar en esta parte real de la aplicación. De acuerdo, así que eso me ahorraría mucho tiempo en el lado del cliente tratando de averiguar, acuerdo, ¿cuál es la llamada? Guerra ellos lo que sea porque este Autorizar
realmente se hará cargo de toda esa situación por mí. Está bien. Por lo que ahora que he autorizado sólo a los administradores para poder acceder al controlador de tipos de hojas. Si estoy conectado como usuario e intento ir a dejar tipos manualmente. Entonces, una vez más, no basta con sólo ocultar el enlace porque si lo memorizo, puedo triangular. Bueno, estás viendo que está viendo el acceso denegado y está apuntando a una dirección que no existe. Bueno, eso está bien. Lo que nos está diciendo acceso denegado, um, o, ya sabes, está reportando que no podemos llegar allí. No obstante, si me iniciara sesión como administrador, fácilmente
podría navegar por allí porque cumplo con los requisitos. Por lo que esa es una buena manera de asegurar su aplicación desde el cliente. Dicho ahora que dicho, también
podrías asegurarlo desde la API dijo porque de la misma forma que puedes configurar que autorizar inundación sobre el controlador de tipos de hoja en el cliente arriba o cualquier tipo de aplicación que estés usando, ya sea un blazer MVC o angular, dondequiera que te sientas, la autenticación en aquellos que pudieras nuestra autorización más bien, también
podrías establecer esa autorización en la API. Por lo que el desarrollador de API también puede tener estipulaciones estrictas en cuanto a quién debería poder acceder a mi controlador porque si no se aplica desde el alcista, y entonces aún podríamos pasar a la API. Entonces como desarrollador de API, también
podrías ser muy estricto y ver que solo los administradores están autorizados para calentar todo este endpoint, todo
este comportamiento, ¿no? O suite de conductas. Entonces como dije, hay pocas opciones y siempre se puede atacar desde diferentes ángulos. Está bien, así que vamos a cerrar toda esta actividad con unas cuantas modificaciones más y entonces estamos libres de casa al menos por ahora. Muy bien, entonces en nuestro controlador de usuarios, en nuestra app, quiero hacer una modificación aquí donde compruebo si el modelo Steve es válido. Entonces si estás usado MVC y todos esos, no
puedes proceder siempre y cuando sean errores de validación y no en Logan VM, sí
tenemos algunas validaciones. Queremos asegurarnos de que esos estén en jaque y no les agradó, esto es todo lo que hacemos cumplir esa validación antes incluso de intentar esa llamada API. Muy bien, de lo contrario sólo agregará ese nuevo, ese error estático y devolverá la vista con los datos y los errores. No hay problema, no para registro. Adelante y estropeemos este. Por lo que sólo vamos a Ver, Nueva Vista, vista de navaja. Queremos registrarse con nuestra plantilla de crear y nuestra clase sería registrar v0 m. acuerdo, así que no estoy seguro si te mostré el registro, registrate VM, pero prácticamente se parece a la solicitud de registro. Registro, solicitudes, Nombre, Apellido,
correo electrónico, nombre de usuario, y contraseña. Está bien, y si quisieras poner a Putin confirme contraseña, pero por ahora eso es todo lo que tenemos. Y también tenemos esos atributos para asegurarnos de que sean requeridos. Entonces vas a usar eso para generar la vista. Y luego en el, en el post, lo que vamos a tener es aceptar ese registro o hay VM? Saber, he hecho una modificación
al método de registro y esto tiene unos pasos a través de él. Uno en el perfil de mapeo de
perfil sumado para el radio la VM y las solicitudes de registro para recordar o distribución a petición es uno de esos modelos generados cortesía de n swag, ¿verdad? Entonces estoy fregando este el punto porque lo escribí pero realmente no me gustó. Entonces una vez más, cuando te estás desarrollando, a veces haces algo de una manera y luego DESPUÉS HACER enfermería. Pude haber sido el centro del poco mejor y va a tener problemas con la refactorización, ¿verdad? Entonces en el método de registro, estoy tomando notas nuestro parámetro de registro VM y también he actualizado o me servicio de autenticación para reflejar eso. Muy bien, Así que nulo, toma ese objeto entero en lugar de seis parámetros. Entonces eso es otra cosa con principios sólidos. No quieres pasar a muchos parámetros a un método. Entonces cuando te des cuenta de que probablemente superes tres o cuatro, crea un objeto. Entonces en este caso sólo teníamos dos. No quería que refactorizara esa, pero entonces ésta tenía como cinco o seis. Por lo que lo refactoricé para simplemente pasar en el objeto de registro. Y entonces nuestra solicitud de registro es no, solo un mapeo entre la solicitud de registro y nuestra VM de registro o registro. Correcto. Entonces por supuesto que tuve que inyectar la parte superior de otoño en esto para ponerlo en marcha. Y entonces todo lo demás sigue igual más o menos. Por lo que de vuelta al controlador. Conozco POS en esa llamada de registro, reviso ¿se crea? Y luego si se crea, entonces redireccionamos. Entonces aquí solo estoy sentando la URL para ser tu contenido. No estoy sentado es específicamente y redireccionamos. De lo contrario, tenemos un mensaje y devolveremos la vista con los datos. Y mostraría todos los errores de validación en consecuencia. Entonces modifiquemos también nuestro servicio de Auth a nivel API porque queremos los empleados se registren por lo que necesitamos saber que sus empleados, por lo que en ese momento se están registrando en base a nuestra cotización es configuración no, que serían sólo usuarios. No habrá asignación de roles en absoluto. Por lo que necesitamos asegurarnos de que cuando se registren, conozcamos a sus empleados. Por lo que en nuestro servicio de Auth, una vez más, en nuestro proyecto de identidad sobre la infraestructura, derecho , servicio
OT, necesitamos ver si el resultado fue exitoso para el usuario de creación. Entonces tenemos que asignarlos a la regla. Por lo que sólo vamos a sumar esta línea después de que un punto de resultado tuvo éxito. Simplemente decimos, esperaré a usar un manager add a regla usuario asíncrono, empleado. Entonces quedemos ese registro para dar un giro. Entonces voy a golpear registro y llenar esto. Ahora una cosa que quería apuntar O, nos
hacemos por el correo electrónico y el nombre de usuario. Una vez más, los contextos son diferentes en nuestro contexto, estoy usando el mismo valor para correo electrónico y nombre de usuario. Y entonces se diría que se podría decir de viable. Se les pide ambos. ¿ Por qué no sólo pedir uno y asignarlo en el cubo, que es argumentos verificables, verdad? Por lo que en tu situación, es posible que los necesites separados, y pueden necesitar ser dos cosas diferentes. De esta manera, no hay problema solo dándote el marco. Entonces antes de que incluso haga una distribución adecuada y
se puede ver que la validación realmente está funcionando activamente. No puedo proceder a que todo esté en su lugar, ¿verdad? Entonces déjame poner los valores y luego seguir adelante y golpear registro. Y me redirigieron aquí. Entonces tienes otra que sabes, siempre
estoy hablando de las opciones porque en este punto estoy registrado, pero no lo sé. No hay indicio de ver que fue exitoso. Acabo de volver a la página de inicio. Por supuesto, si intento iniciar sesión, puedo iniciar sesión pero el usuario no lo sabe. Por lo que en términos generales, o a veces lo que verías es que realmente te
iniciarían sesión después de una distribución exitosa o exitosa. Por lo que podemos hacer una simple modificación para que eso suceda. Eso es simple modificación es llamar o autenticar arte. Entonces pasamos por su distribución, obtuvimos una respuesta si no está vacía y volveríamos verdad. Antes de que
volvamos verdad, sólo queremos llamar autenticar, que sabemos lo que hace. En realidad desencadena todo ese procedimiento de inicio de sesión, y luego regresamos true. Entonces en nuestro controlador, fácilmente
podríamos tener algo de redirección para ver, en lugar de volver a la página principal, en realidad
podríamos leer nuestras dos direcciones IP. Tendrás banner de amor exitosamente, algún mensaje amistoso para el usuario para que sepan exactamente lo que ha pasado. Está bien, entonces eso es realmente todo para nulo, al
menos más adelante tenemos el embellecimiento tendremos algunas modificaciones porque incluso hasta en el nulo, no
estamos enfocando ni compensando ciertas flechas que harían estar regresando de la API. Entonces adelante. Dijimos que manejo global de errores para cuidar, pero más adelante nos ocuparemos de eso, ¿verdad? No, solo nos estamos centrando en implementar estas características y hacer que todo funcione bien en conjunto.
33. Configuración de la dirección del permisos: Muy bien chicos, así que ahora que tenemos o configuración de autenticación, tenemos a nuestros usuarios, o al menos nuestros usuarios tienen la capacidad de autoregistrarse y ser configurados como empleados. Y todo lo que necesitamos poner en la característica que permita
a los administradores asignar los Ds para sentarse a los empleados. Por lo que eso comienza con los que modifican nuestros objetos de dominio para asignación de licencias donde vamos a agregar el ID de empleado porque necesitamos saber a quién se le ha asignado el número de días para este tipo de hoja para ese periodo. Por lo que tenemos que añadir eso. Y luego siguiendo eso, hacemos una migración. Recordando que necesitamos poner nuestro proyecto de startup a la API y el proyecto por defecto al proyecto de persistencia. Y o agregar dash La declaración de migración se verá así. Nombré mi ID de Empleado Agregado para dejar asignación y los contextos serían contexto de base de datos de gestión de licencias. Y después de eso ejecutamos esa actualización al mismo contexto. Entonces este es nuestro archivo de migración. Simplemente haces la base de datos de actualización y un suelo que está terminado y podemos seguir adelante. El siguiente que queremos hacer es crear un archivo de contrato o una interfaz en nuestra capa de aplicación bajo la carpeta de identidad, lo
estoy llamando, uso un servicio. Por lo que vamos a tener cualquier operación de usuario especializada en esto, utilizo un servicio que puede ser utilizado por nuestros manejadores. Entonces voy a tener este devolviendo una lista de tipo empleado y se llama el get employees porque sólo queremos asignar. Estos son los empleados saben que el departamento de RRHH dijo que todo lo que realmente necesitan para esta característica es la capacidad de ir a la página y hacer clic en asignar, y luego obtenemos a todos los empleados y asignamos. El defecto es para el periodo, periodo siendo este año. Por supuesto, no queremos destinar
nada a ningún organismo que no esté en el rol de empleado. Por lo que necesitamos asegurarnos de que estamos consiguiendo empleados. Empleado es un modelo que se creó dentro de la carpeta de identidad. Y todo lo que realmente tiene es el ID, el correo electrónico, el FirstName, apellido, y nada demasiado, no demasiado viniendo de la base de datos solo en un bosque y todo lo que podría ser este empleado. Gracias, tenemos nuestra implementación la cual vive en el proyecto de identidad, y es sólo utiliza el servicio bajo la carpeta de servicios. Y está heredando del contrato. Y se está inyectando el administrador de usuarios en relación con el usuario de la aplicación. Y entonces nuestro método para conseguir la lista de empleados solo estaba buscando en el administrador de usuarios, conseguir usuarios inscritos asincrónicos y pasamos en ese rol. Entonces esto nos está garantizando que estamos consiguiendo cualquiera en la base de datos fuera un usuario que tenga rol de empleado. Y luego estamos devolviendo la lista de tipo empleado. Entonces, ¿dónde se encuentra esta una lista de usuario de la aplicación? Por lo que estamos diciendo seleccionar de esta lista en nuevos objetos de tipo empleado. Y apenas estaban reasignando los valores en consecuencia. Y luego lo terminamos con una lista de cosas por hacer todo en ese retorno. Entonces una vez que se llame a este servicio, vamos a estar usando ese método para conseguir a todos los empleados. Entonces en nuestro método de registro de servicios
de identidad, por supuesto tenemos que agregarlo I Servicio de Usuario. Por lo que sólo vamos adelante y lo registramos en consecuencia. Ahora esto va a ser seguido de algunos cambios en nuestro repositorio de asignación dejo. Así que salta de nuevo a los contratos y encuentra nuestro original. Dejaré repositorio de asignación. Originalmente habríamos escrito la implementación para las capacidades actuales completas de asignación de licencias junto a estos dos métodos personalizados. Pero luego HR, una vez más, tipo de reglas de cambio lo hicieron más simple para nosotros, problema de sono, pero sí necesitamos algunos métodos más personalizados para lograr lo que HR tenía en mente. Entonces bien, no, tengo una tarea, estamos devolviendo un booleano que comprueba si existe la asignación. Por lo que obtenemos el ID de usuario, ID de tipo de
hoja y el periodo. Y entonces tenemos otra tarea donde estoy viendo en asignaciones. Entonces vas a ver por qué tengo en asignaciones, pesar de que ya tenemos el método de add genérico, el estado sabe que éste toma como parámetro una lista de
asignación de licencias , conociendo la implementación. Eso ya verás lo que está pasando aquí. Entonces empecemos con la aplicación existe. Una vez más tarea devolviendo un booleano, comprobando si existe, obtenemos estos tres parámetros, por lo que solo estamos regresando DB context dot leave asignaciones que cualquier asíncrona donde comprobamos si el ID de empleado coincide con el ID de usuario siendo delgada. Si la hoja tipo ID mucho es uno que se está pasando y el periodo tanto como el periodo. Entonces sólo estamos regresando, sí, esa asignación existe, son conocidos por nuestras asignaciones estaban haciendo algo un poco diferente aquí entonces con el anuncio regular. Porque lo que pasa es que si estamos si estamos permitiendo que
ELLA simplemente vaya y haga clic en Agregar asignaciones y ahí hay 100 personas. Lo que no queremos hacer es llamar a la función add 100 veces. Por lo que EF Core en realidad nos dio un método de rango de anuncios que
nos permite simplemente poner en una lista completa de registros a agregar. Y lo empaquetará en la sentencia SQL más eficiente posible para guardar los cambios. Está bien, así que por eso escribí ese método personalizado aquí. Por lo que estamos agregando rango en lugar de agregar. Muy bien, así que ahora que tenemos nuestro repositorio está hasta cero, Vamos a saltar a nuestro manejador y ver qué cambios se necesitan por ahí. Está bien, así que en nuestro manejador había comentado estas líneas son solo descomentarlas saben que estamos aquí. Por lo que estamos inyectando nuestro servicio de usuario en nuestro comando o creamos la asignación. Conoce algunos otros cambios serán necesarios porque nuestro detalle de creación está pidiendo demasiada información en base a lo que dijimos. El nuevo operativo o el nuevo objetivo es. Llegaremos a eso en unos pocos. Pero la retina quiere enfocarse en lo que hace manejador después de que
sea, ha validado los datos que vinieron, correcto. Por lo que después de validar lo que hay en el DTO, procedemos entonces a tratar de compilar la lista de asignaciones a enviar a la base de datos. Entonces veamos qué pasa aquí. En primer lugar, obtenemos el tipo de hoja que se está asignando, ¿verdad? Entonces haríamos OBTENGO solicitudes debajo ese repositorio el cual ya se inyectó cortesía fuera del Fatah. Lo necesitábamos para el validador. De acuerdo, así que deja ese repositorio dot GET solicitud punto asignación ingenua detalle el elif tipo ID. Obtenemos a todos los empleados cortesía de nuestro servicio al usuario. Nosotros también fijamos el periodo este año. Y luego inicializamos una lista de asignaciones de licencias. Entonces para cada empleado que está en el sistema, comprobamos si existe la asignación. Simplemente continuamos. De lo contrario queremos agregar un nuevo registro de asignación donde el ID de empleado sea igual a EMP dot ID y dejar dy by dt es igual al tipo de hoja pero ID y el número de días. Y el periodo es el periodo correcto? Ahora bien, no estoy siendo estricto con las reglas de negocio. Algunas reglas de negocio dirían que con base en el punto del año, esa ubicación debería ser diferente, lo cual es perfectamente plausible. Sea lo que sea masi fuera a hacer, aplicas esa matemática contra los días por defecto y aplicaste. Pero el punto es que estás asignando los días al empleado en este punto. Por supuesto, si quisieras conseguir ese Grendel, entonces querrías hacerlo de uno a uno en lugar de
una operación a granel para todos durante todo un periodo de un año, ¿verdad? Para que puedas jugar un poco con él. Pero ahora mismo solo estamos lidiando con una operación a granel. Entonces después de haber agregado todos esos registros de asignación a esta lista, entonces sólo esperamos nuestro llamado a las asignaciones en nuestro repositorio, que está enviando a través de la lista y EF Core, haremos el resto. Y entonces podemos ver la respuesta es verdadera, el éxito es cierto más bien, y el mensaje es la creación o asignaciones exitosas, cualquiera que prefieras. Conoce por nuestros crea asignación DTO, estamos pidiendo el número de estos. Y estábamos pidiendo el periodo porque al menos en el viejo sistema, que son capaces de hacer click directamente sobre un empleado y poner en el número de hojas que estamos destinando dinero salvajemente. Y el periodo para el que lo estamos asignando, como dijo RRHH, como que no necesitan o no quieren eso, ¿verdad? No, Así que eso está bien. Siempre podemos simplemente modificar nuestro DTL, escalarlo un poco. Y por supuesto, eso tendría algunos efectos de onda con el conjunto la herencia de los detalles de asignación. Entonces eso significa que tenemos que modificar más que solo los campos, ¿no? Por lo que tendría que quitar esta herencia y la nota off para modificar también el validador para no incluir todas las reglas relativas a la interfaz son OF quitar todo
este incluir Andoni fuera después de reescribir la regla solo para el Crea. Por lo que acabo de reescribir esa regla donde validamos el ID de tipo de hoja que se está solicitando se asignan, nos aseguramos de que sea mayor a 0 y comprobamos si existe también. Ahora saltemos a nuestra API y le hagamos saber
que también debería estar devolviendo la respuesta del comando base. Si no lo has hecho ya. Asegúrate de hacerlo para que el documento Swagger con lo actualizado y luego dos cambios deban ser contabilizados por nuestro nuevo cliente de servicio en la aplicación. Porque uno, cambiamos los parámetros para el DTO. No, solo necesitas un parámetro. Y también necesitamos que el servidor sepa que debe esperar la respuesta del comando base. Entonces ahora que hemos hecho esos cambios, Utilicemos en swag para regenerar estos código de cliente de servicio. Sólo recuerda siempre que lo mejor es ejecutar el proyecto. Y luego aunque ya lo tengas guardado, porque acabo de abrir mi versión guardada de esta plantilla. Incluso si lo tienes guardado, lo mejor es reabrir el proyecto, recrear la copia local, y luego podrás regenerar tu código C-Sharp. Entonces ahora saltamos a nuestra aplicación cliente donde estaremos configurando nuestro contrato, Son implementaciones y por supuesto, la interfaz de usuario. Entonces ahora mismo todos tenemos nuestro contrato. Dejaré el servicio de asignación y nos dice que hay respuesta de devoluciones con tipo int. Y se va a llamar creativamente vocaciones, y sólo está tomando una identificación tipo hoja. Una vez más, RHH lo simplificó para nosotros. Entonces si hubieras creado todas las máquinas virtuales y así sucesivamente, Eso es lo que tengo eso habría sido exagerado en base a los nuevos requisitos, pero eso está bien. Entonces todo lo que realmente necesitamos es crear una IV asignaciones. Y luego en la implementación que ponemos en la carpeta de servicios, por supuesto, sabemos que heredamos del servicio HTTP base y el ID del servicio de asignación, muy parecido a lo que hicimos, los tipos de hojas, también
inyectamos o de bajo costo almacenamiento y AAE Client en este servicio. Y luego en nuestro método,
esas son sus asignaciones de licencia de creatinina, todo lo que tenemos nuestro tipo de respuesta, que es respuesta relativa al tipo int. Creamos nuestro detalle, que en esta situación es realmente solo el detalle a ver. El tipo de hoja tiene ese valor. Está bien, así que sabemos el Crear, dejar, crear dejar asignación detalle ahora se actualiza para solo querer ese valor ya que actualizamos nuestra documentación y el código resultante a través y babosa, agregamos a nuestro token portador y somos trigo llamar. Muy bien, así que ni siquiera soy la verdadera puede, siempre
podemos duplicar y asegurarnos de que el endpoint de la API esté protegido sólo para administradores. Y también podemos hacer esa predicción desde nuestro lado de la aplicación, ¿no? Por lo que el token al portador es definitivamente importante recordar. Siempre va a ser importante para las comunicaciones apec. Entonces después de hacer eso, comprobamos si tu éxito entonces lo pusimos a cierto ya que no hay datos reales regresando, porque sólo estaban regresando la respuesta de la B. No vamos a devolver una identificación ni algo así. Por lo que no necesito establecer los datos de respuesta para tener algún valor realmente. Y entonces nosotros los errores del compilador devolvieron respuesta. Tocar cualquier error. Como dije antes, asegúrate de que lo tengas registrado en el punto de inicio CSS. Entonces simplemente no haces balas ni el startup.js. Y si había escrito las líneas, sin comentarlas, entonces sin comentar, si no, entonces siéntase libre de saber, poner esta línea. Ahora hagamos cambios o interfaz de usuario. Entonces el mejor lugar que he supuesto para poner esta característica para
una asignación a granel de tipos de hojas es en el tipo de hoja LR. Entonces en esa página acabo de agregar un nuevo formulario donde
tendremos abogado con el mismo tipo de visado ID de ruta chicos para verlo buscando fórmula para borrar. Entonces aquí estamos repitiendo la forma. Entonces como mencioné, a veces pitido, en lugar de tener múltiples formas, tendría una y luego usaría JavaScript para activar la única forma. Pero eso está bien en esta situación, todo lo que quiero saber es que funciona bien? Por lo que tenemos el ASB real y asignar. Se necesita el mismo ID de ruta y tenemos un botón que dice asignar. Y éste solo está diciendo: ¿
Estás seguro de que quieres destinar a todos los empleados? Ese es el prompt que obtendrías. Ahora tenemos un método de post en nuestro controlador de tipos de hojas llamado Hello Kate. Entonces solo puse esa justo debajo de la eliminación, ¿verdad? Entonces en nuestro caso, estamos tratando de obtener la respuesta del servicio de asignación de licencias. Por lo que subpunto dijo que tenemos que inyectar eso en nuestro controlador. Muy bien, Así que tratamos de conseguir la respuesta. Simplemente uso Control M y O, solo nota a tipo de colapso todo el código para que puedas usar eso para archivos de código B. Por lo que nuestro método de asignación va a llamar al servicio de asignación crear altercados, pasando en ese ID. Y luego si redirigirá con éxito a la acción al índice. Y bueno, sólo voy a devolver mala solicitud aquí por si acaso no tuvo éxito. Entonces sabemos que no fue ella. Posteriormente puedes agregar algo de jQuery o algo para manejar el tipo de retorno de una mejor manera, pero correcto, no, no estamos priorizando eso. Simplemente queremos asegurarnos de que estamos poniendo todas las cosas y la fundación en su lugar, ¿verdad? Entonces, en realidad tomemos ese para dar una vuelta. Tratemos de asignar. Recuerda poner en múltiples proyectos de puesta en marcha. Y habiendo ingresado como usuario administrador, navegamos a nuestros tipos de hojas y luego tratamos de asignar. Entonces aún nuestro prompt ¿Estás seguro de que hacemos click Ok, y estamos recibiendo un error. Estamos recibiendo un error, HTTP Error 400. Por lo que esto está indicando esa mala solicitud. Está bien, Entonces algo definitivamente salió mal. Por lo que después de rastrear y rastrear ese error, aterrizó justo aquí en el validador. Entonces lo que pasa es que cuando estamos creando, no
se está viniendo como válido que crear asignación de licencias V2 no está siendo válido. Eso se debe a que está viendo que no existe un tipo de hoja. Ahora sabemos que eso es imposible porque acabamos de hacer clic en el tipo de hoja. Está en la misma línea. Sabemos que existe y la flecha está justo aquí. Entonces esa es mi, uh, pero así i pruebas unitarias probablemente habrían cogido que alguna vez escribimos en unittest. Entonces tenemos que pasar tiempo rastreando estas cosas no. Pero el punto es que Deberíamos estar regresando si existe, porque estamos viendo si existe o es cierto. Por lo que debe existir. Entonces esto debe ser cierto. Por lo que no debería estar regresando, no
regresando verdad o no airear. Entonces eso es un error de mi parte. Entonces por ese error, en realidad tendrá que ir a cada validador sólo para estar sano. Así que asegúrate de que ninguno de esos validadores esté cometiendo ese mismo error. Ahora lo bueno es que como que creamos los centrales. Entonces no tenemos muchos, muchos cambios para mí. Entonces los que despegan que no firman el tipo de hoja existe, checa y deberíamos estar bien para ir. Muy bien, así que intentemos esa otra vez. Tratemos de hacer las asignaciones. Muy bien, entonces estamos de vuelta y luego intentemos asignar de nuevo. Llegamos a nuestro prompt, hace lo suyo, y la página se actualiza para que no haya indicadores, ¿verdad? Podríamos por supuesto, citando algunos mensajes para decir, ya
sabes, esta acción llamará a los terminados con éxito. Pero el hecho de que realmente refrescara la página de acuerdo a nuestro código. Si tiene éxito, entonces redirigir al índice de la playa actual, lo cual es bueno. Fue infructuoso por lo que en petición de mantequilla. Por lo menos sabemos que nuestra asignación está funcionando. Vamos a revisar en la base de datos para ver cuáles se han creado nuestras ubicaciones. Y aquí vemos que tenemos asignaciones para hoja tipo uno para el periodo de 2021 y el empleado al que se le asigna. Por lo que tenemos tres empleados en el sistema o empleados de IL-3 en mi sistema, probablemente solo
estamos viendo uno o dos si tienes al usuario sembrado y él creó un usuario desde entonces. Pero el punto es que tenemos tantos empleados están en el sistema, ustedes tendrían esas asignaciones. Entonces si lo hago de nuevo con seguridad, que es id2, click, localizo, click Ok, y hace lo suyo. Si actualizo estos datos, ahora vamos a ver asignaciones para licencia por enfermedad para todos los empleados. Por lo que la asignación div no está funcionando. Eso es lo que la obra de arte de RHH, eso es lo que obtienen. Por lo que más adelante ves el de la fundacional para extender esto, si quisieras dar una pantalla dedicada, tendrías que ir a pescar al empleado, permitirles editar la asignación del valle del dinero. Y luego, ya sabes, para configurar tu manejador y tu endpoint API para que sean específicos a eso. No vamos a conseguir eso detallado ahora mismo. Simplemente queremos que se hagan las funciones base. Y hasta el momento estamos terminados con asignación de licencias.
34. Gestión : parte 1 - Empleador: Muy bien chicos, entonces estamos devanando aunque Nestlé y estamos pasando al siguiente módulo, que será nuestro módulo de solicitudes de licencia. Por lo que nuestro viaje aquí comienza con una modificación a un objeto de dominio de
solicitud de permiso donde estamos agregando solicitando ID de empleado, bien, porque quien haya iniciado sesión es quien va a estar haciendo la solicitud. Por lo que necesitamos poder decir que esta solicitud vino de este usuario. Como de costumbre, tras una modificación a nuestros objetos de dominio, tenemos nuestro comando de migración y luego tenemos nuestro comando de actualización de base de datos. Para que puedas seguir adelante y hacer esos dos. Y una vez que hayas completado con éxito eso, podemos pasar a nuestra siguiente actividad. Revisemos nuestros detalles Crear solicitudes de licencia. Por lo que dijimos que la Quest D2 necesita tener la fecha sería fechas de inicio y fin, el tipo de hoja que se está solicitando, así
como solicita comentarios. Aviso que no hay nada terrible el ID de usuario, ¿verdad? Entonces probablemente te estés preguntando, vale, entonces ¿cómo sabemos qué usuario está conectado a la vez? Entonces recuerda que estamos usando la autenticación Tolkien, lo que significa que entre el MVC arriba en la API, podemos acceder a diferentes bits de información desde el Tolkien. Un poco de información en el token sería el ID de ese usuario. obstante, no quiero acceder a ella desde ninguno de estos lugares porque no necesito acceder a ella hasta que realmente estoy creando solicitud de permiso. Y tenemos el manejador aquí que se toma, ese comando solicita o comandos objeto. Y luego va adelante y
validándolo y luego creando que la solicitud si es válida, luego pasarla la base de datos. Por lo que eso significa en medio de estos dos pasos, necesitamos asegurarnos de que ponemos esos nuevos datos de identificación de empleado. Entonces recuerda que habíamos utilizado el accessor de contexto buck cuando estábamos haciendo la autenticación en la aplicación MVC. El genial de esto es que somos capaces de usar ese accessor de contexto todo el camino aquí en nuestra capa de aplicación, en nuestros comandos. Entonces vamos a acceder al contexto HTTP de la API desde dentro del manejador. De esa manera no tenemos que acceder a ella hasta que sea absolutamente necesario. Entonces en el archivo de inicio de API, voy a agregar el services.js HTTP context accessor de escritura, la llamada al método swat Swagger doc. Esto, entonces me permite inyectar en el comando mi accessor de contextos HTTP. Y puedo seguir adelante e inicializar el campo, pero sí necesito una biblioteca para esto, y esa es la abstracción de núcleo ASP NET de Microsoft dot. Así que adelante e instala la última versión. Estoy usando NuGet, renombrar nuestro campo de acuerdo a nuestra convención de nomenclatura. Y luego dentro del manejador, puedo guardar fácilmente el ID de usuario var es igual a mi contexto HTTP accessor dot contextos HTTP, dot user dot reclama default de primer orden. Entonces es bastante bocado, pero solo evaluemos lo que está pasando aquí. Hasta este punto, hemos conseguido el principio de reclamos. Ese principio de reclamos es el mismo principio que somos capaces de construir en la aplicación de inquilino en virtud del Tolkien, de acuerdo, por lo que debido a que el token está viniendo de nuestro cliente a la API, podemos acceder a la información del token del manejador cortesía de la API. Y luego podemos acceder a ese Usuario, mirar dentro de la lista de reclamos y encontrar el valor predeterminado del primer piso que tiene la misma clave de tipo de nombre. No obstante, se quiere evaluar que lo que un tipo aquí corresponde con el nombre reclamado que le habríamos dado para ID de usuario. Entonces esa es otra razón por la que sugeriría no usar las cuerdas mágicas porque un error ortográfico aquí podría tirar todo el asunto. De qué podemos hacer eso en la actividad de limpieza más adelante. Pero ahora mismo estamos obteniendo ese UID de reclamo, que nos sentamos manualmente. Y luego solo estoy usando el valor predeterminado o cuatro, si es pequeño, no
obtenemos otra excepción, pero realmente estoy obteniendo el valor. Está bien, así que así es como consigo el ID de usuario. Ahora que tengo este ID de usuario, más adelante puedo ver solicitud de permiso punto solicitando ID de empleado es ID de usuario. Ahora lo hice todo el camino hasta aquí porque quizá quiera usar este ID de usuario y otra operación más adelante. Entonces sólo lo estoy guardando aquí. Y otra cosa que nos podría interesar es la dirección de correo electrónico. Entonces no aquí estamos recibiendo el correo de una manera ligeramente diferente. Estamos viendo la dirección de correo electrónico es igual a su accessor de contextos GTP, todo ese usuario.name encuentra primero. Y luego estamos buscando el reclamo exacto por correo electrónico por su tipo. Ya que hace una técnica diferente a lo que hicimos aquí arriba. Y estamos obteniendo ese valor. Por lo que puedes tomar múltiples enfoques para conseguir esto. Estos bits de información porque podría haber conseguido
el principio de reclamos en un solo barrido y luego usar la ley find first, la primera ley default después para obtener el pedacito de información que quieras. No hay problema, pero al menos usted sabe o sabe cómo obtener la dirección de correo electrónico para que podamos saber decir a esa dirección de correo electrónico y enviar nuestro correo electrónico en el momento adecuado. Ahora antes de pasar de este manejador en particular hay otras
operaciones de limpieza arriba me gustaría llevar a cabo antes de
permitir que un usuario proceda con una solicitud de licencia. Y así pensemos qué es exactamente lo que debe suceder durante este proceso. En un usuario necesita declarar que quiere tener un cierto tipo de hoja durante un cierto periodo. Pueden agregar comentarios adicionales si así lo desean. Y luego someten eso. Sólo pueden obtener esa solicitud si tienen la asignación. Entonces eso significa que ni siquiera lo vamos a poner en el sistema. Si lo que han solicitado supera su asignación actual. Si lo solicitan y su asignación está presente, entonces eso está bien. Posteriormente, cuando un administrador apruebe esto, entonces vamos adelante y hacemos algunas deducciones para
asegurarnos de que cuando ellos si solicitaron cinco días, entonces el 5D sea menor en su asignación. Entonces esas son las cosas que queremos estar atentos. Ahora esto es un, este es el más complicado de los módulos. Por lo que aquí hay bastante trabajo por hacer. Entonces empecemos con la comprobación de la asignación, porque si no tienen la asignación, entonces no pueden tener una operación válida en adelante, ¿verdad? Entonces sigamos adelante e inyectemos o dejo repositorio de asignación en el sistema. Y entonces lo que queremos hacer es poder
buscar la asignación para este empleado en particular, que es un método que no tenemos R. Así que saltemos a esa historia e implementemos eso. Entonces estamos creando una tarea que devuelve asignación de dejar, estoy llamando asignaciones de GetUser y está tomando ese ID de usuario de cadena así como ID de licencia, correcto, así que vamos a saltar por aquí y seguir adelante e implementar el en la clase de repositorio de implementación. Y entonces lo que vamos a hacer aquí es hacer una búsqueda y
devolver nuestro contexto DB buscando asignaciones de licencia,
encontrando devolver nuestro contexto DB buscando asignaciones de licencia, el valor predeterminado de primer orden donde el ID de empleado coincide con
el ID de usuario y el ID de tipo de hoja coincide con la hoja. No se abrochó el manejador. Puedo seguir adelante y obtener esa asignación llamando al repositorio de asignación de
permisos asignaciones de usuario de Git, pasando el ID de usuario y esa solicitud de salida de punto, solicitar detalle punto hoja tipo ID. Ahora voy a calcular el número de días solicitados. Entonces solo estoy haciendo un caucásico rápido entre la fecha de fin y la fecha de inicio para obtener el número total de días. Y me estoy asegurando de que lo consiga pero como un entero. Y luego voy a decir si el número de días solicitados es mayor al número de días en su registro de asignación. Voy a agregar este error de validación. Entonces esta corporación podría haber pasado aquí, justo como estamos viendo, lo
estoy haciendo manejador y estoy usando el resultado de validación fluida para solo agregar eso porque en caso de que no sea válido, quiero asegurarme de que esta validación también sea presente. Y así cuando se devuelva con los errores que también estarán ahí. No, estoy haciendo esto en el manejador, pero podría haber hecho esto fácilmente en el validador también. Pero entonces por supuesto habría tenido que inyectar todo esto y crear una validación personalizada en el NDA para asegurarme de que hago ese cálculo y todo. Entonces solo te estoy dando las opciones en función de tu situación. Es posible que desee mantener todas esas cosas dentro de los validadores. Es posible que ni siquiera estés usando validador. Por lo que podrías estar haciendo toda esta validación aquí mismo. Depende de cómo quieras diseñar tu código de aplicación. Entonces ahora solo podemos seguir adelante y limpiar cualquier otra cosa en este manejador, tal vez
tengamos que volver a visitar los datos, pero al menos estamos viendo cómo expandimos nuestro manejador y empezamos a poner algunas otras cosas en su vida HTTP, contexto, manejarlo, acceso u otro, lo siento. Entonces, cuando seguimos adelante, puedes limpiar cualquier pequeño mensaje en
el camino y asegurarte de que tu código pueda compilar. Entonces solo una compilación rápida. Ahora avancemos rápidamente a nuestra app. Queremos conseguir la función en donde un empleado puede solicitar licencia ante todo antes de poner en cualquier otra característica administrativa y cualquier cosa, ¿verdad? Por lo que quiero que nos aseguremos de que tengamos ese modelo de vista. Yo lo hubiera mostrado antes, pero deja solicitudes VM y sube todos los modelos de vista aquí. Y estos modelos de vista realmente vienen del código existente en gran medida. Entonces el Create leave requests, VM, y eso toma la fecha de inicio, la fecha de finalización, la hora, el ID de hoja, y algún área para comentarios. No, yo saltaría al contrato por el
servicio de solicitudes que dejo donde tenemos algunos métodos que no estamos implementando todos ellos por ahora, estamos lidiando con un crédito para que puedas seguir adelante y ponerlos todos dentro. Y crear la implementación del servicio coincidente y permitirle implementarlos todos. Pero al enfocarnos en el método de creación, lo que tenemos es núcleo de aspecto similar a lo que hicimos con los tipos de hojas. No obstante, notarías que tengo una línea roja debajo de la parte donde estoy pidiendo respuesta. Eso se debe a que en lo que respecta al servicio de IA, cliente o, o código de inserción todavía sólo
estamos buscando una tarea. Eso es porque en la API, necesito hacer dos cosas. Necesito dejar que la documentación o que en post, debería tomar la respuesta de comando base. Recuerda que habíamos equipado a todos nuestros manejadores para devolver esto. Y esto es esencial porque cuando usamos n swag para regenerar o codificar, lo cual estoy a punto de hacer, entonces sabrá que debería esperar este tipo de respuesta. Una vez más, crea la copia local más reciente, sigue
adelante y genera y sabe que eso se hace cuando salto de nuevo a mi código, no
hay líneas rojas porque ahora sabe
que está devolviendo la respuesta del comando base. Entonces todo está bien. Muy bien, entonces eso es básicamente lo que estamos haciendo en crear la solicitud de hoja. Entonces, centrémonos ahora en configurar el controlador y el código de soporte. Seguí adelante y creé un controlador con operaciones de
lectura-escritura, ya sabes, para hacer eso, No. Y yo inyecté el servicio tipo hoja y permiso solicita servicio. Entonces probablemente te estés preguntando, vale, ¿por qué necesito el tipo de hoja y permiso de servicio si solo estoy creando solicitudes de licencia, bueno, la cosa es que la vista que ya he creado necesita tener un drop- lista abajo para los tipos de hojas porque cuando alguien viene a solicitar licencia, se basa en tu flujo. Pero la forma en que lo estamos construyendo, vienen a solicitar, dejan eso apagado para seleccionar de una lista desplegable qué tipo de licencia están seleccionando, la fecha de inicio, la fecha de fin. Y luego son capaces de poner en sus comentarios antes de seguir adelante y seleccionar solicitud. De acuerdo, entonces eso es básicamente lo que estoy haciendo y esta es la vista que viene del viejo sistema. Por lo que literalmente he copiado y pegado esta vista desde el viejo sistema. La única actualización fue que cambiamos el modelo para que sea el nuevo modelo en contraposición a cualquier nueva especie que haya allí. Pero sólo te estoy mostrando que es la misma clase. Por lo que siempre puedes ir a obtener el archivo de código y solo copiar y pegar. Y debes estar hasta el rasguño como cantidades de alfa. Es por eso que esto está aquí. No estoy usando ningún recolector de fechas. Todavía no estoy complicando la interfaz. Entonces estoy quitando eso. ¿ Becker amigos Nuestros cuentas de tipo
de entrada que acaba de usar dependiendo del Selector de fecha predeterminado que nos ha dado el navegador. Por lo que Buck en el controlador, necesitamos preparar esa lista desplegable antes de la carga de la interfaz. Entonces en lugar de cuatro, get Create method, lo que tengo es una llamada al servicio tipo hoja para obtener todos los tipos de hojas, almacenarlos en esta variable. Y luego tengo ítems tipo hoja donde estoy creando una nueva lista selecta con tipos de
hojas y usando id y name como la clave y los campos de texto. Y luego estoy creando el nuevo modelo donde estoy pasando en tipos de hojas como elemento tipo hoja. Por lo que recordar crea solicitudes de licencia. Teníamos ese ojo público innumerable select this item property, y esto fácilmente podría haber sido selecto lista. ¿ Está bien? Entonces cualquiera que funcione, pero nos deja trabajar con selecciónelo porque en realidad es más fácil escribir sobre el trabajo con. Entonces eso es todo lo que está pasando aquí. Y luego regresamos la vista mostrando el modelo. Conociendo el método de publicación, prácticamente
seguimos el mismo procedimiento si el estado modelo es válido. Porque recuerda que en nuestro modelo de vista tenemos algunas reglas de validación, por lo que queremos asegurarnos de que todo se cumpla antes de poder proceder. De hecho, solo me estoy dando cuenta de que me falta una regla de validación sobre el ID de tipo de hoja en sí. Por lo que deben seleccionar un ID tipo hoja antes de poder proceder. De acuerdo, así que déjame solo espaciarlos todos para que puedas ver todo. Ahí vamos. Entonces si el estado modelo es válido, entonces adelante y ancho en la respuesta del trabajo de servicio de solicitud de licencia, que va a intentar crear una solicitud de licencia. Y luego si tiene éxito, entonces podemos redirigir al índice. no hay página de índice aquí,
pero eso no es problema. Y luego podemos agregar cualquier modelo,
modelo de flechas de estado proveniente de nuestros errores de validación de respuesta. Pero entonces si la página tiene que recargarse, lo que necesitamos hacer es recargar realmente la lista selecta de tipos de hojas, ¿verdad? Entonces una cosa con listas desplegables en caso de que no estés tan familiarizado con ellas. En cualquier momento que estés cargando la página, tienes que cargar esa lista. Por lo que cargamos la página primer nivel, donde cargar esa lista, luego devolver el modelo. Tenemos que hacer lo mismo aquí. ¿ Cuáles ya tenemos los datos que vienen del modelo? Por lo que solo necesitamos reasignar los datos a la lista de selección recién cargada antes de devolver el pH junto a cualquier error que deba mostrarse. Ahora, apuesto a autorizar el discurso que es bastante estándar en este punto. Y en nuestro archivo de maquetación tenemos algunos cambios. Por lo que he puesto los enlaces ahí solo para que los empleados puedan ir y crear nuestra vista. Mi hoja, aún no he hecho mi permiso, pero aquí están nuestros enlaces, ¿verdad? Entonces en el mismo Eso es comprobar si el usuario está autenticado. Ya veo si es un empleado el que está conectado porque los administradores no tienen asignaciones, por lo que no necesitan ir y solicita irse, ¿verdad? Entonces si es un empleado el que está conectado, entonces pueden ver dos nuevos cisne NoveLink yendo a solicitudes y crear. Y dice que las peticiones se van, aunque me voy a ir, que aún no hemos hecho, pero estamos llegando despacio pero seguro, ¿verdad? Entonces después de hacer todo eso, sigamos adelante y pongamos o múltiples proyectos de inicio una vez más y probemos esto. Entonces ahora voy a iniciar sesión como administrador de usuario, pero el empleado. Y una vez que hago eso, veo mis dos enlaces en la barra de navegación. Entonces cuando voy a las solicitudes de salida, estoy recibiendo este error. Es un error 403 y lo veo y sé exactamente por qué. Por lo que he mencionado que aún estamos por compensar todas las excepciones que podrían lanzarse a través de la API. Este es uno de ellos. Se trata de un 43 que es una excepción No autorizada. El problema es que cuando estábamos probando los puntos finales del donante del lote hotelero, habíamos puesto al administrador autorizado en todos los controladores de tipos de hojas. Entonces conoce a este empleado necesita que le muestre la lista de tipos de hojas. La aplicación está haciendo esa solicitud en este endpoint, pero no es administrador. Entonces lo que podemos hacer aquí es t el autor está apagado o al menos la estipulación de roles fuera de lo autorizado y sólo autorizar los que están aumentando los datos para que el post
PUT y elimine esos ajustes realizados. Podemos volver a intentar esta operación. Y voila, así que no, podemos navegar con seguridad allí como empleado. Entonces tratemos de solicitar las hojas de vacaciones. Entonces creo que este rubro, se
puede ver que va todo el camino de regreso a enero, supongo el inicio de los tiempos, siempre
podemos establecer los predeterminados porque probablemente no quieras esa extensión de tiempo. Pero no vamos a hacer eso. Farnell, lo que haré es simplemente seleccionar el primero de enero al 5 de enero y notar que es mes, el año. Ese es el formato que está usando. Todo eso es personalizable, pero no vamos a entrar en todo el original. Por lo que licencia de vacaciones. Y luego cuando solicito salir, estoy recibiendo otro error. Entonces este error, es decir que el parámetro no puede ser nulo. Entonces sospecho que esta es una flecha regresa de nuestra API que no se está manejando una vez más, pero entremos al modo de depuración y veamos exactamente cuál es el problema. Y aquí está el culpable. La parte genial está en nosotros tratando de conseguir la dirección de correo electrónico. Entonces déjame retroceder un poco. Sí tenemos al usuario, tenemos los reclamos. Y si miras ahí dentro, sí
tenemos el reclamo de dirección de correo electrónico. Está bien. Por lo que la dirección de correo electrónico está presente. No obstante, creo que estoy usando el valor de reclamo equivocado aquí. Digamos si vuelvo a donde se generó el JWT, que está en el servicio de autenticación. Yo sí usé el mismo nombre de reclamo que era simplemente correo electrónico. Correcto. Entonces si hago clic con el botón derecho o control-click, verás que es solo un correo de texto estático. No obstante, en contraste, en realidad está viendo esa limpia con una clave diferente. Y esa clave está más ajustada al esquema de jabón XML. Y ese tipo de reclamo en realidad, o ese texto estaría presente en tipos limpios. Entonces déjame parar y seguir adelante y cambiar eso a tipos limpios pensamiento email. Por lo que falló en la recuperación de la dirección de correo electrónico y por eso no lo hicimos. Bueno, tienes ese error, ¿verdad? Entonces si revisamos nuestra mesa de solicitudes de licencia, estoy bastante seguro de que en realidad vamos a ver algunos datos, ¿verdad? Entonces ven aquí sí tenemos licencia de vacaciones y es por lo tanto cada vez que se compró, ¿no? Por lo que efectivamente está funcionando. Apenas estaba fallando en la recuperación de la dirección de correo electrónico. Entonces con ese arreglo, deberíamos poder proceder a sin trabas. Pero entonces sí ves que algo completamente ajeno a la operación clave causó la falla, razón por la
cual intentamos todo este try catch para solo enviar el correo sin molestar todo lo demás. Bueno entonces vemos que esto también es un punto de fracaso. Concedido, acabamos de arreglarlo. Bueno, teóricamente podríamos tomar esto y también colocarlo dentro del try catch para que cualquier cosa relacionada con el correo electrónico no arroje un error. Ahora que tenemos el proceso de solicitud, no nos dejes tomar un descanso y cuando
regresemos veremos su proceso de aprobación.
35. Gestión : parte 2 - Admin: Ahora que tenemos nuestra solicitud de licencia sobre el empleado dijo: No. Tenemos que poner en realidad algunas otras cosas para que el administrador pueda realmente ver las solicitudes pendientes y aprobar o rechazar. Ahora, esto viene con algunos cambios de ruptura para resolver los manejadores y algunas otras solicitudes, algunos de los detalles, bastantes cosas que hemos hecho hasta este punto, pero como de costumbre, solo te
guiaré por todas las modificaciones necesarias en algún lugar para empezar off con la grasa que en realidad se adelantó y creó que clase de constantes de costo para los tipos de reclamo se discuten. Eliminando las cuerdas mágicas como poner en UID muchos-cuerpo, ¿verdad? Así que creé un tipos de reclamos personalizados, solo una clase estática pública. Está en constantes bajo el proyecto de aplicación. Y tenemos contras públicas String UID es igual a UID. Por lo que esto ahora nos permite en el servicio de auth decir fenotipos de vestuario dot UID y pasar eso en y en cualquier otro lugar que podamos necesitar hacer referencia a este tipo de llanura costera como lo hicimos en los otros manejadores. Entonces solo podemos seguir adelante y decir tipos de reclamo personalizados dot UID. Conoce otra modificación que estoy haciendo es a nuestro servicio al usuario. Tenía un método para conseguir que todos los empleados ahora tengan otro para obtener solo un empleado basado en el ID de usuario. Está bien, entonces en la implementación de ese método, básicamente solo digo Consígueme el empleado encontrar por ID y luego estoy devolviendo un nuevo objeto empleado con los diversos campos incluidos. Saber también he actualizado nuestra lista de solicitudes de licencia, DTO, y he agregado las fechas de inicio de la hora de inicio, y efectivamente, esas no estaban antes, así
como el objeto empleado y la identificación del empleado solicitante. Por lo que saber cuando el administrador está viendo la lista de solicitudes, pueden ver cuáles son las solicitudes, las fechas de inicio y las fechas de fin de solicitud de cetera, así
como los detalles de la persona que lo ha solicitado, habría realizado un modificación similar a las solicitudes de licencia donde nos hemos asegurado de incluir información de los empleados. Ahora bien, una rápida modificación al mapeador y en este punto es opcional porque quiero que pienses críticamente, no solo hagas lo que hago, sino que pienses en ello. Contamos con un campo llamado datos solicitados en la licencia solicita objetos de dominio. Por lo que eso fue creado como se modeló fuera del sistema anterior. Ahora recuerda que estamos refinando el sistema y
deshaciéndonos de algunos de los despidos y cotizar caracoles. Y creo que esta es una de esas cotizaciones corre porque la fecha solicita que realmente es la fecha creada. Por lo que ya estamos captando la fecha. Se crea cada registro. No tengo que volver a poner lo solicitado, y francamente, no hicimos eso en un manejador cuando entró la solicitud. Entonces lo que estoy haciendo aquí sin embargo es que realmente estoy haciendo un mapeo, nuestro mapeo personalizado para nuestros ciertos campos. Entonces estoy viendo que cada vez que estés mapeando desde el objeto de dominio al DTO, mira en el detalle o el destino, y obtén el campo de fecha solicitada. Y luego quiero que eso se mapee directamente a lo que
esté en el campo creativo y deje objeto de dominio de solicitud. Está bien, así que una vez más, eso es opcional. Qué sinceridad, cómo las tarifas que solo te estoy mostrando el poder de parte superior
otoñal nos ayuda a recién crecer, asegurarnos de que todos los datos estén ahí,
es lugar relevante y apropiado. Ahora, pasando a nuestros manejadores. Por lo que he hecho algunos cambios en el manejador de solicitudes de
licencia y asignación y pérdida de licencias tanto para la lista como para el detalle. Entonces empezaré con la lista ya que esa creo que tiene más cambios que no. Entonces uno, he modificado la solicitud para tener esta bandera para decir es usuario conectado, es
decir, estamos tratando de obtener la lista de solicitudes de licencia para el usuario conectado son para un administrador. Entonces en el manejador, estoy inyectando el accessor de contextos HTTP así como lo uso. No creas que esos ya están ahí antes. Conoce algunos inyectándolos y cualquier otra cosa que no había antes. No, siéntete libre de seguir adelante y replicar. Pero luego dentro del manejador, lo que estoy haciendo de manera diferente, no, estoy inicializando las solicitudes de permiso este top, top. Y tengo otra lista para el detalle que se va a devolver, que en este caso es dejar solicitudes lista PTO. Entonces estoy comprobando si la solicitud dice que es para el usuario conectado o no, ¿verdad? Entonces si es para el usuario conectado, quiero seguir adelante y conseguir ese ID de usuario ahí. Estoy usando mi constante, ver qué bonito y limpio se ve eso. Está bien, así que estoy obteniendo el ID de usuario y luego en realidad he implementado otro método para obtener solicitudes de licencia con detalles relativos al ID de usuario. Entonces vayamos a esa implementación de método. Entonces en el contrato para dejo solicitudes que tengo que obtener solicitudes de licencia con detalles, la original que escribimos juntos y esta nueva con el ID de usuario string. Por lo que uno con el ID de usuario básicamente solo agrega en una condición donde el ID solicitante en el registro es igual al ID de usuario que se está pasando. Todavía incluimos los detalles del tipo de hoja y enviamos de vuelta esa lista. Ahora después de hacer todo eso, utilicé el servicio de usuario para conseguir al empleado relativo al ID de usuario que es, ahí. Y luego hago un mapeo desde el objeto de dominio a nuestro detalle. Entonces para cada objeto de solicitud en la lista de solicitudes o detalles, estamos asignando a ese empleado valor para ello. Por lo que una vez más, esto sería si estoy conectado como usuario y quisiera ver mi lista de solicitudes. Esto va a manejar eso. Ahora si el administrador lo solicita, es más o menos lo mismo que antes, donde simplemente los sacamos a todos con los detalles. Y luego por cada solicitud, realidad
vamos a buscar al empleado sobre la marcha, ¿verdad? Entonces mientras que conocemos al empleado porque soy el usuario conectado, entonces es sólo uno de mí. No sabemos que haya muchos empleados diferentes. Entonces para cada solicitud, vamos a buscar a ese empleado y ponerlo dentro de eso. Y al final del día, regresamos las solicitudes. De igual manera, estoy haciendo una operación similar para las asignaciones de licencias, donde estoy buscando todas las asignaciones de la base de datos tienen un método similar y prácticamente este código se ve igual. Muy bien, así que de la misma forma que agregamos la solicitud de licencia de asignación ingenua con detalles relativos al ID de usuario. Es de la misma manera implementado método como ese para o dejar asignaciones donde el ID de empleado es el ID de usuario y somos los mismos if statement. Nosotros hemos agregado el mismo tipo de inundación a nuestra solicitud, ¿verdad? Por lo que solicitanos quién está conectado usuario y luego tenemos la declaración if. Si está conectado, entonces más o menos el mismo procedimiento que acabamos de ver. Relativo a asignaciones de licencia. No obstante, entonces tengo obtener solicitudes de licencia detalle. Entonces es cuando quieres una solicitud de permiso. Entonces imagínalo. Cuando el administrador ve la lista de solicitudes de licencia, él o ella necesita hacer clic en esa solicitud
de licencia luego ir a una pantalla para ver si
está pendiente, si está aprobado o poder aprobar cientos o rechazado en ese momento. Correcto. Por lo que he modificado las solicitudes get con detalle donde he puesto en esta línea para incluir la información del empleado. Por lo que prácticamente toda la modificación hasta el momento se acaba lanzar en el incendio que necesitamos poner en esa información de empleado. Entonces como hemos actualizado esa clase de solicitud, necesitamos saber, dejar que nuestro endpoint o comportamiento refleje este nuevo parámetro, ¿verdad? Entonces en el get, voy a pasar en un booleano. ¿ Es el usuario conectado que buscamos? Si es lo que estoy incumpliendo en caídas, ¿verdad? Entonces así es como puedes poner un parámetro por defecto donde si no das un valor, entonces es falso, ¿verdad? Entonces, independientemente de su valor, lo
pasaremos al objeto de solicitud y luego el manejador cumplirá con la decisión como acabamos de ver. Por lo que he hecho esto tanto en las asignaciones de licencia como en las solicitudes de licencia manejador consigue. Como de costumbre, una vez que actualices tu EPA, cualquier cosa con el azul se giró para tener algo en el controlador, quieres volver a ejecutar y empaquetar y obtener una copia fresca de ese código de cliente. No quiero saltar de nuevo a nuestra aplicación cliente. Vamos a ver nuestro contraste. Por lo que los siguientes a los que quiero absolutamente poner atención serían el
aprobar la solicitud y obtener la lista de solicitudes de licencia admin. De acuerdo, y también necesitamos obtener solicitudes de licencia por DNI. Por lo que al menos esos tres necesitan ser implementados ahora mismo. Entonces tengo otros métodos ahí, y para el final de este curso se implementarán. Pero no voy a pasar demasiado tiempo ventana en el agujero de conejo de tratar de conseguir cada característica en. Para este módulo, sólo nos vamos a centrar en que el empleado pueda
pedir permiso y que el administrador pueda aprobarlo o rechazarlo. Por lo que después de haber incluido esos tres métodos en el contrato, pasamos a la implementación. Entonces por supuesto a estas alturas estoy seguro de que has actualizado tu código de cliente. Entonces todo lo que tengo aquí debería funcionar para ti. Entonces para la solicitud de licencia aprobada, lo que estamos haciendo es tomar int id y la bandera o el booleano para ver es aprobado Sí o no. Entonces vamos a formular o solicitudes donde
colocamos cambio de licencia solicitud de aprobación detalle, y pasamos en ese aprobado y el DNI. Y luego esperamos al cliente llamando a aprobación de cambio asíncrona, donde envía el id y la solicitud. Nuestra solicitud de licencia obtiene es bastante directa. Es solo devolver solicitudes de permiso vista modelo. Agregamos nuestro token al portador por supuesto, que también hicimos en el aprobar la solicitud. Y luego seguimos adelante y lo intentamos y Fitch desde las solicitudes de licencia de get-go, obtener una sincronización con mi ID y devolver la versión trapeada de solicitud de licencia en forma de la hoja solicitud ViewModel. Eso lo veremos en unos cuantos una vez más. Siguiente método digno de mención sería las solicitudes de licencia get admin por lista. Ahora voy a explicar lo que voy a buscar es en la aplicación original sobre lo que habíamos hecho fue que obtuvimos todas las solicitudes de licencia y tratamos de agruparlas y después. Averiguar es por el total de solicitudes de licencia, es por cuántas están aprobadas pendientes, etcétera, etcétera? Eso es exactamente lo que estoy haciendo aquí. Por lo que estoy recibiendo todas las solicitudes de licencia y notas esta vez tengo ese parámetro se registra en el usuario colon falso. Sólo estoy nombrando el perímetro. Esta parte en realidad es opcional, pero me parece útil. Entonces eso es que no puedo recordar lo que realmente significa el valor en términos de la llamada de función. Pero estoy de paso en caídas porque este no es el usuario conectado. Este es el administrador, ¿verdad? Entonces el administrador está recibiendo todas las solicitudes de licencia y luego solo estoy creando ese modelo admin leave requests view model. Y estamos pasando el número total de solicitudes, cuántas son aprobadas, rechazadas, y poniendo en la lista de solicitudes de licencia en general, y estamos devolviendo el modelo. Está bien, Entonces, una vez más, ¿
todos son el levantamiento pesado ocurre dentro del servicio? No, dentro de nuestras configuraciones de mappings, he actualizado eso para reflejar algunas de las nuevas asignaciones que podemos esperar. Por lo que para un detalle de solicitud de licencia para dejar solicitud VM, hay una ligera diferencia en el tipo de datos entre las escrituras. Muy bien, Entonces de un lado tenemos datetime, pero luego el detalle que se genera vía o en código swag en realidad nos da un offset datetime. No estoy del todo seguro de por qué hace eso, pero la solución sería que cuando estamos mapeando, solo decimos cuatro miembros aseados solicitados, adelante y mapearlo desde la hora punto-punto solicitada. Y eso lo hacemos para la fecha de inicio, y lo hacemos para la fecha de fin. Y eso realmente se encargará de ese error. Entonces si no haces esto, si quieres probarlo, puedes comentarlos. Intentar ejecutar el código que requeriría mapeo. Y luego verías ese error superior de otoño diciendo que el mapeo está fallando para los campos relacionados con Beta. Está bien, así que puedes hacer eso para las solicitudes de licencia para dejar solicitudes, VM, dejar solicitudes lista detalle a las solicitudes de licencia VM. Y luego además de esas nuevas, también
tengo una aquí para el empleado donde también he creado el empleado VM, que se parece al empleado ETO saber dentro de las solicitudes de licencia ver archivo modelo. Repasemos sólo algunos de los modelos de vista, al
menos los que son absolutamente necesarios para que completemos esta actividad. Por lo que hemos agregado la VM de empleado con empleado dentro de esta vista modelos, por
supuesto, en última instancia veremos dos propiedades cualquiera con el mismo nombre. Tratará de mapearlos, ¿verdad? Por lo que se implica que el empleado mapeará al empleado desde el detalle hasta el ViewModel, ¿verdad? También tenemos la solicitud de administrador ViewModel que no necesariamente miramos antes, no. Entonces así es como estos campos y solicitudes totales, solicitudes aprobadas, solicitudes pendientes, solicitudes rechazadas, y la lista de solicitudes de licencia. Para que puedas seguir adelante y asegurarte de tener representación para el ViewModel en tu código. Pero volviendo a nuestra licencia solicita controlador es C. Saben que tengo tres nuevas acciones son 14, el índice, una para los detalles y otra para aprobar solicitudes. Entonces índice que tomará modelo y este modelo será de tipo admin leave Solicitudes Ver VM o como está llamando el servicio de solicitud de permiso punto get, admin lever, quest list son el administrador verá esta página donde una vez más esas estadísticas y la lista de solicitudes pendientes estarán en exhibición. Nuestro método de detalles básicamente estará ahí para cuando estén viendo la lista y hagan clic en uno de los ítems. Y luego queremos ir a buscar que dejan solicitudes con todos sus detalles y devolver la vista en consecuencia. Entonces tenemos el Aprobar Solicitudes, no aprobar solicitudes básicamente verá adelante y aprobar la solicitud, it HTTP post. Por lo que vamos a poner una granja en esa página donde vamos a llamar a esa pasando esa licencia solicitud de identificación así como si está aprobada o no. Entonces si están aprobando o rechazando cualquiera, pasará
eso. Y luego estás viendo cómo pasa a la API, al manejador y lo que ocurre antes de implementar esos puntos de vista. No obstante, sólo quiero que hagamos un seguimiento completo de lo que sucede cuando se apruebe. Entonces voy a saltar a las actualizaciones, al manejador de solicitudes que también ha sufrido cierta cantidad de cambios. Y te guiaré a través de ella. Es, por supuesto que pausas y replicas como necesites. Por lo que sabemos inyectando el
repositorio de licencia Qi Shun además de cualquier otra cosa que se estaba inyectando en este archivo. Y la razón de eso es que necesitamos poder deducir la asignación cuando haya una aprobación. Entonces lo que estamos haciendo aquí es refactorizar nuestro método manejado para esto. Entonces obtengo las solicitudes de licencia en primer lugar, y luego veo si estamos tratando con un detalle de solicitud de licencia de lo que quiero
ejecutar la validación porque lo que estaba pasando inicialmente o la forma en que escribimos el código inicialmente, el se estaba ejecutando el código de validación independientemente de que esto fuera nulo o no. Conoce si la prueba de validación para validar nuestro nulo, entonces eso también va a arrojar un error. Y tirar todo. Por lo que solo estamos validando nuestra solicitud de licencia DTO cuando está presente. Y luego si todo está bien, vamos adelante y hacemos nuestro mapeo y nuestras actualizaciones. Ahora. De lo contrario, si es el cambio dv solicita detalle lo que no es nulo, que en este caso de aprobarlo es entonces no es
más que esperar la licencia solicita repositorio cambiar estado método de aprobación pasando en la solicitud. Y la gorda fuera queríamos nuestra probada. Entonces voy a decir si el detalle de aprobación de cambio de punto de solicitud, eso es aprobado, valor de punto, si eso es cierto, ¿verdad? Es todo esto realmente evalúa equivalente a verdadero. Pero claro, cuando se trata de booleanos, no necesariamente hay que ver equivalente a verdadero. Sólo podemos ver si el booleano, ¿verdad? Y no tenemos que preocuparnos por otra excepción porque siempre debe
ser, siempre debe tener un valor. Entonces ese es otro objeto que podemos hacer hacia el detalle porque ahora mismo creo que lo hicimos anulable, lo cual no, pensamos en ello está mal. Siempre debe tener tanto valor que voy a quitar ese booleano y podemos actualizar nuestro código de cliente swag en consecuencia, pero más adelante podemos hacerlo. Entonces estoy actualizando ese detalle para que siempre sea verdadero o falso. Entonces si es cierto, entonces obtenemos la asignación para el empleado. Por lo que la asignación var es igual para obtener aplicaciones de usuarios. Este es un nuevo método. Entonces este nuevo método, una vez más, lo
pones dentro del contrato. Pero cuando lo implementas, básicamente
es tomar la cadena usando el ID de usuario y el ID de tipo de hoja. Entonces vamos y decimos, tráeme la asignación de hojas. En primer lugar, nuestro asíncrono predeterminado, donde el ID de empleado mucho es el ID de usuario que se está pasando y el ID de tipo hoja coincide con el que se está pasando. Por lo que después de hacer todo eso, pasamos al empleado solicitante junto a las solicitudes de licencia. Entonces tenemos la petición de salto aquí. Contamos con el empleado que lo solicitó y conocemos el tipo de hoja cortesía de la solicitud una vez más. Y luego vamos a decir, dame el número de b, ¿verdad? Por lo que ya vimos que en la creación están en la solicitud más bien, cuántos D's se están solicitando. En esta situación, se podría tomar otra decisión. Podrías decidir almacenar el número de Ds en la base
de datos desde el principio o calculado sobre la marcha como estamos haciendo, no. Entonces eso depende de ti. De cualquier manera obtenemos el número de cervezas, vamos adelante y adoptamos el número de éstas de la d se solicita del número de días para la asignación. Y luego ejecutamos una actualización para esa asignación, luego regresamos. No, en cuanto a nuestros puntos de vista que mucho nuestros controladores, hemos creado el índice y hemos creado los detalles. A decir verdad, el índice es una copia dividida de lo que viene del viejo código. Entonces si has descargado todo el código fuente o puedes simplemente bien, Está en GitHub. En realidad puedes sacar todo de esa página de índice de solicitudes de
licencia coincidentes y por favor aquí, no
he modificado nada. Cualquier modificación que se necesite sería debido a las diferencias de nomenclatura. Por ejemplo, aquí tengo item.name empleado en lugar de item.name solicitante empleado. Fuera de eso, sin embargo, el código es bastante el mismo. Ahora, para los detalles, he hecho algunas modificaciones porque en el código original, habíamos repetido esta sección de alerta sobre tres veces. Y lo que hicimos fue decir, de aprobarse, entonces mostrar este código de alerta con un nombre de clase diferente en texto oculto diferente. lo contrario si es cierto, entonces muéstralo de nuevo con derecho. Entonces en lugar de repetir esto y esa es otra parte, seca, no te repitas. Entonces entra factor, siempre quieres decir, bueno, algo tiene que repetirse en algún momento, ¿verdad? O alguna operación necesita ser rehecha. Pero cuál puedo rehacer con el menor camino de resistencia R, que sería más fácil de mantener a largo plazo. Entonces mi refactorización de lo que se hizo en los detalles originales pH sería que estoy creando dos variables aquí. Uno interesante, uno para encabezamiento, texto de encabezamiento. Y luego si la aprobación es nula, entonces doy ClassName y golpear toma sus valores. Si es cierto, les
doy diferentes valores, etcétera, para. Y luego cargo el div con el
otro en un momento donde paso dinámicamente en ese nombre de clase y textos de encabezamiento, porque todo lo demás dentro de esa alerta va a ser igual independientemente, ¿verdad? Entonces digo nombre de empleado y luego pongo en Model lot empleado nombre y apellido. El día solicitado es que solicitaron regresar de la modelo. Y entonces prácticamente todo lo demás es igual hasta la última parte donde estamos comprobando si está aprobado o no. Entonces en lugar de tener que vincular botones ya
que el código original los había arriba en granjas donde discutían por qué los foros son mucho más seguros. Por lo que para el método post es la solicitud de prueba del axón. Y en éste tengo el ID que es un oculto, y tiene un valor para la idea del módulo también tener otro oculto que tiene el nombre aprobado y el valor es verdadero. Repito esa alimentación para el rechazo, excepto que el valor para el aprobado es falso. Entonces cuando hagan clic en cualquiera de estos botones va a llamar a aprobar solicitudes, que luego va a conseguir identificación y costos aprobados que no sólo pasamos por lo que hace el manejador con toda esa información. Muy bien, entonces tenemos este módulo desde hace bastante tiempo, y este suele ser el módulo más difícil y que consume mucho tiempo. He intentado reducir el tiempo tanto como sea posible, pero luego hay mucho más por hacer, pero al menos tienes los conceptos fundacionales para que puedas tomarlo y seguir adelante. Entonces, solo previsualicemos cómo se verán estas solicitudes de
licencia desde el punto de vista del administrador. Y las solicitudes semanales de cleave verán la lista de solicitudes de licencia. Entonces ya aprobé y rechacé uno y así se ve ese código. Y éste está pendiente de aprobación y vemos la fecha de inicio, la fecha de fin, el tipo de vacaciones, el nombre del empleado, todo está bien y, ya
sabes, nos escupe. Entonces si hago clic en revisar, pasamos a la página donde dice pendiente de aprobación que
solicitaron y luego puedo aprobar o rechazar. Entonces si hago clic en Aprobar, entonces redirigirá asumiendo que no hay errores. Y en realidad hay un error. Muy bien, Así que el problema aquí es que estoy usando el código del create con el fin de hacer el cálculo, cual es completamente incorrecto porque debería estar usando el objeto de solicitud de palanca y no solicitar punto leave solicita detalle, derecha, así que déjame actualizar eso y podemos reintentar esa operación. Está bien, así que intentemos de nuevo. Voy a dar click Aprobar. Y ahí vemos que no está aprobado. Conocer el problema que vamos a tener que abordar más adelante es el hecho de que tenemos múltiples operaciones que se están llevando a cabo contra múltiples mesas. Pero, ¿adivina qué pasó? Un participante y la otra parte no lo hicieron, lo que significa que esto fue aprobado, pero la deducción no ocurrió porque tuvimos una falla en ese lago. Correcto. Por lo que en realidad hicimos con éxito la aprobación, pero luego la parte de deducción no pasó, por lo que no se actualizó. Y lo que quisiéramos hacer es hacer algo así como nuestro papel buck, debería ser todo o nada. Entonces si una parte campos entonces todo debería sentir. Entonces ahí es donde
entra en juego la unidad de trabajo tipo de trabajo o a nivel de base de datos lo llamamos transacciones. Por lo que más adelante veremos todos esos problemas de limpieza con nuestra aplicación. Siempre que una aplicación así de grande, hay
que mirar hacia fuera esas cosas.
36. Unidad de trabajo para las operaciones de lotes: En esta lección, vamos a estar configurando un middleware global de manejo de excepciones para nuestra API. Entonces lo que pasa es que teníamos excepciones
personalizadas que creamos desde casi el inicio del proyecto. Hemos estado lanzando excepciones en ciertos puntos de nuestros manejadores. No obstante, no hemos dicho necesariamente la API entera que debe responder cuando se lanzan excepciones. Entonces por supuesto, querrás fallar siempre con gracia si hay un tipo de excepción, queremos enviar de vuelta un código que sea indicativo del tipo de excepción. Por ejemplo, he actualizado todos mis manejadores de actualización para lanzar también una excepción no encontrada. Entonces después de saber, déjame simplemente corregir este. Tan abierto a saber. Yo no tenía el código. Si ya tenías el código, entonces eso está bien. Eso son saludos para ti, ¿verdad? Pero estábamos lanzando excepciones de validación cuando la validación falla. Pero entonces lo que pasa si el registro que se encuentra no era teléfono, entonces queremos una excepción no encontrada. Por lo que he agregado que en cada cheque para ver si se encuentra asignación de licencia, si la licencia solicita, Eso es un barco para actualizarse su teléfono y si la licencia lo siento, el tipo de hoja, su objetivo. Si el tipo de hoja es de teléfono, simplemente
lanzamos una excepción no encontrada. ¿ Está bien? Por lo que lanzar la excepción es bastante fácil. Manejarlo es otra cosa. Por lo que ten en cuenta que no hay tramos de capturas. Sería una especie de avance dominante tratar de poner el try catch y cada uno. Entonces lo que vamos a hacer es configurar y manejar excepciones middleware a nivel API porque el controlador usa medios para llamarlo manejador, pero tampoco tenemos ninguna pista de capturas aquí, así que siempre estamos regresando, ¿de acuerdo? Pero luego hay momentos en los que se lanza la excepción y se Ok, se puede lanzar. Y en la API es literalmente solo lanzar algo de buck de respuesta aleatoria en el cliente. Queremos asegurarnos de que sepamos lo que se está lanzando. Así que adelante y crea una nueva carpeta en el proyecto API llamado middleware. Y en esa carpeta crear un archivo llamado middleware de excepción. Entonces ese es nuestro middleware de excepción cruzada. Y sólo voy a guiarte a través de lo que esto va a estar haciendo en web o detalles. Entonces tenemos una clase en ese archivo, en esa otra clase llamada detalles de error. Solo te estoy guiando por las partes más simples primero. Y los detalles del error solo tiene el tipo de error y un mensaje de error. Entonces al menos siempre podemos informar al cliente esto es lo que salió mal en
base a la circunstancia con la que nos enfrentamos ¿verdad? Ahora. Todo decía que tenemos dentro de la clase para middleware excepcional, tenemos campo privado de solo lectura llamado siguiente, y eso es de tipo request delegado. Por lo que instanciamos eso en el constructor. Y entonces tenemos un método llamado invocar un fregadero. Por lo que asyncTask público invocan async y toma un parámetro llamado contextos HTTP. Por lo que ya tipo de miramos lo que los contextos HTTP nos permiten hacer. Básicamente, nos permite ver la solicitud, la respuesta, todo con un flujo de trabajo completo entre cliente y servidor se almacena dentro de estos contextos HTTP. Entonces esto va a estar actuando como un interceptor, se va a tratar de ver. Se va a decir hacer la siguiente opción que se debe completar vía los contextos HTTP. Eso es básicamente lo que eso está haciendo. Ella. contextos http hacen su siguiente opción. Si hay una excepción, vamos a atraparla y entonces la manejaremos. Ahora, pasemos a cómo lo manejamos. Por lo que la excepción de manejo de tarea privada es hundir donde le
da el contexto HTTP y la excepción que fue capturada. Conoce solo estamos diciendo que queremos que una respuesta punteada sea aplicación slash JSON porque es la API. Entonces sabemos que todo lo que respondamos va a ser en forma de JSON. También estamos configurando un error interno de servidor predeterminado, código de estado
HTTP escuela está por defecto a lo que es 500. Entonces vamos a decir que el resultado es igual a, nunca
quiero serializar objetos en una nueva instancia de flecha con el mensaje de excepción. Muy bien, entonces estamos serializando todo esto en los resultados nulos cuando vamos al interruptor. Donde básicamente ver qué tipo de excepción es este, porque la excepción es el tipo de datos base. Pero entonces como hemos visto, tenemos nuestras propias excepciones. Tenemos la excepción de validación, tenemos el déjame salir la mantequilla solicita excepción. Tenemos la excepción no encontrada. Por lo que podemos dar cuenta de todos estos contabilizando por mala solicitud. No estoy contabilizando la validación. Yo. Adelante y actualiza eso. Entonces lo que estamos haciendo aquí ahora es ver decirme qué tipo de excepción es. Sé que es una excepción, pero de qué tipo fue realmente no fue tan mala petición. Una excepción de validación más bien debe su no me encuentran. En base al punto que hay que hacer es que vamos a cambiar el statu quo. Entonces es moratoria a 50, 100. Significa que si solo fue lo poco excepcional, tal vez fue en falla a nivel de base de datos, tal vez fue una falla de red que no podemos abrochar. Y cuatro, entonces definitivamente es un 500. 500 significa que es un sistema, el sistema que está usando la API, es culpa del sistema. No obstante, las malas peticiones indicarían que tienes la culpa como cliente, pero me enviaste datos de basura. Entonces les voy a decir que es una mala petición, que es una hace 400 años. Si es una excepción de validación, eso también es una especie de mala solicitud porque me enviaste pero datos, pero siempre puedes mirar a través y ver qué otro código podría o mejor para el tipo de excepción. Está bien, pero entonces siempre quieres quedarte en el rango 400 con códigos de error, ¿verdad? Entonces ahí es donde estamos. Entonces quiero decir para ti Eso está solo. Entonces este dice Pero solicitar y luego no encontrar excepción es un 40 por significado no pude encontrar lo que estás buscando. Entonces 40 para así si ninguno de estos era el caso, entonces simplemente rompemos y eso quedaría como un 500. Después vemos responder con el código de estado y regresar con el resultado. Resultado, lo que significa ese mensaje completo que formaba parte del mensaje de excepción. Entonces recuerda que cuando estamos configurando nuestras excepciones o lanzando nuestras excepciones a nuestros cazadores, siempre
estaban sentados el mensaje. Y ese mensaje es lo que se está serializando aquí. Me están enviando bokeh desató esa respuesta. Nulo si quieres que sea un poco más explícito. Porque todo lo que estamos haciendo es enviar sobre flecha con mensaje de excepción, podríamos usar nuestros detalles de error. Podría haber dicho nuevos detalles de error y luego mensaje de
error sería el mensaje y el tipo de error podría ser otra cosa. Entonces yo diría Eric Type Tool y luego probablemente sólo decir fracaso, nuestro error, lo que sea para que puedas ponerte creativo. Es decir, depende de ti lo que, una vez más, esto es lo que obtendrían en su respuesta, lo que sea que pongas ahí. Entonces un modo que hemos terminado de configurar ese middleware, necesitamos saltar al archivo de inicio para API. Y inserto de la Configurar sexual. Vamos a decirle que use el middleware. Entonces solo lo voy a hacer justo por encima de todo lo demás. No quiero decir que hasta DOT use middleware, excepción en middleware. Adelante y agrega cualquier referencia que falte. Y ahí vamos. Por lo que todos tenemos nuestro middleware tratando de atrapar globalmente y luego manejar con gracia cómo responde a cualquier cliente que sea su vocación. Solo quería volver a saltar a la implementación una vez más y tener un ajuste rápido. No sé por qué tenía si esto fuera fuera inicialmente. Entonces con los resultados para la excepción de validación, definitivamente
queremos que los errores de excepción estén yendo Buck en el cuerpo, ¿verdad? Entonces los mensajes de validación, una cosa, bien. Pero entonces queremos que los resultados sean iguales a la serialización JSON de la validación de las flechas, ¿verdad? Por lo que una vez más, tienes muchas opciones sobre cómo manejar la situación. Entonces estamos sentando el mensaje de excepción por defecto, pero lo estamos anulando en el caso del error de validación. Entonces será la lista de errores.
37. Gestión de excepciones de API: Muy bien chicos, bienvenidos de nuevo. Esta lección se inspira en el punto de falla que vimos cuando
estábamos cambiando el estado de aprobación de las solicitudes de licencia, vimos que se completó una parte de la operación y la otra parte falló. Pero entonces necesitamos que ambas partes funcionen realmente antes de poder actualizar la base de datos. Entonces lo que estamos haciendo ahora es montar lo que llamamos una unidad de trabajo, que básicamente dice que tengo todo este trabajo que hacer. Tengo todos estos puntos de contacto. Voy a hacer todas las operaciones y luego hacer un último compromiso con la base de datos, o
vamos a tener éxito o no. Entonces lo que teníamos era que cada repositorio guardara los cambios por su cuenta. Entonces si esto, si hubiera una operación que requiriera dos repositorios para guardar en un lado que en los otros campos, entonces tendríamos en datos consistentes en la base de datos y queremos evitar eso. Por lo que he ido adelante y he configurado esta unidad de contrato de trabajo para que sepamos dónde viven los contratos en tu carpeta de persistencia de aplicación I unidad de trabajo. Está heredando de yo desechable. Y básicamente es sólo hacer referencia a las tres interfaces de repositorio que conocemos. Muy bien, entonces dejo asignación, dejo solicitudes y tipo hoja, y tiene un método que dice Guardar nodos implementación vive en la misma carpeta que la implementación para los otros repositorios. Por lo que esa es la unidad de carpeta repositorios de capa de persistencia de trabajo. Por lo que dentro de esta implementación, estamos heredando de las unidades de trabajo. Tenemos nuestro contexto DB siendo inyectado en. Muy bien, y hemos hecho referencia a todo el repositorio, así que tengo campos privados para cada repositorio. Tan mal guiado este archivo está actuando como si me registrara para los repositorios que tenemos, quiero mantener los repositorios únicos. ocasiones se vería realmente una unidad de trabajo donde se construye alrededor de los repositorios genéricos. Entonces, y cada implementación será simplemente genérica porque hay tantos métodos únicos en nuestros repositorios quieren mantener aquí el repositorio único. Entonces más tarde domo, en realidad tenemos la propiedad pública que mucho es cada uno y déjame solo BreakLine para que puedas verlo más claramente. Entonces el público, dejo repositorio de asignación, se va a llamar DV repositorio de alegatos. Yo básicamente solo estamos realizando lo obtengo así que estamos viendo, Consígueme el campo privado y si es nulo en inicializar una nueva instancia de
la implementación del repositorio de asignación de hojas y pasar en ese contexto que nosotros inyectarlo en. Porque recuerda que cada implementación tiene ese contexto siendo inyectado en. Está bien, entonces por eso tenemos que asegurarnos de inyectar en el contexto y luego se lo pasamos a cada uno. Por lo que esas tres líneas parecen prácticamente la misma barra en los nombres y los tipos a los que se hace referencia. Entonces tenemos un método de disponer el cual se va a llamar en segundo plano donde
simplemente desechamos el contexto y luego suprimimos la recolección final de basura. Y entonces nuestra tarea de ahorrar va a tener nuestros cambios de guardar. Entonces, en otras palabras, estarás haciendo todo sería poner, estaríamos agregando, estará haciendo lo que sea. Estos repositorios tienen que hacer de manera individual, pero entonces estamos haciendo una final Guardar. Muy bien, entonces después de que hayas implementado eso o has replicado todo esto. Echemos un vistazo a algunos de los cambios que se requieren en los otros repositorios. Entonces, empecemos con un repositorio genérico. Antes de lo que teníamos eran individuos Guardar Cambios en el anuncio, la eliminación y los métodos de actualización. De acuerdo, entonces ahora estoy recibiendo esa Groenlandia porque
ya no hay una llamada asíncrona dentro de estas tareas asíncronas? Bueno, podemos abordar eso más adelante, pero mi punto es que he eliminado todas las líneas de Guardar Cambios de estos métodos en particular porque
no queremos que vean si tenemos que hacer múltiples cosas. Se desea agregar algo y eliminar algo y hacer una actualización. Queremos un último compromiso con la base de datos. Todo o nada por unidad de trabajo están en cada manejador. Porque recuerden, los manejadores básicamente están lidiando con escenarios. Por lo que queremos que se complete el escenario completo, todo o nada. Por lo que hemos eliminado todo el mar de cambios del repositorio genérico así como de cualquier otro repositorio individual que pudiera haber tenido un Save Changes siendo usado ahí. Entonces como en asignaciones donde el promedio tenía que guardar cambios, he eliminado eso. Y en las solicitudes de licencia teníamos los cambios de Guardar que se estaban haciendo dentro de ese método para actualizar, derecha. Para cambiar el estado de aprobación, eliminé todo eso. Ahora con esas mudanzas, necesitamos actualizar nuestros manejadores para adaptarnos apropiadamente. Entonces voy a saltar a las solicitudes de licencia de Crear, y les voy a mostrar exactamente qué tipo de refactorización pasaría. Uno, habríamos estado interactuando con dos o tres repositorios en este manejador. Por lo que habría inyectado dejo repositorio, dejo repositorio de asignación, etcétera, etcétera. Conoce solo tenemos que inyectar o una unidad de trabajo. Y antes de avanzar más, permítanme simplemente señalar que sabemos que tenemos que
registrarlo en lugar del registro de servicios de persistencia. El mismo lugar que habrías registrado todos los repositorios donde apenas estamos iniciando nuestra unidad de trabajo ocular. Por lo que eso lo convierte en componentes inyectables. Muy bien, entonces ahora podemos reemplazar todos los individuales por la unidad de trabajo I. No, te enfrentas a un montón de líneas FRD. Bueno, saber dónde tenías el repositorio de tipo de licencia de subrayado como el campo privado. Ahora puedes reemplazar eso por unidad de trabajo dot leaf type repositorio porque le estás dando el mismo repositorio justo a través de la unidad de trabajo. Entonces esto es como nuestro padrón para todos los repositorios fuera de mí. Mención de eso antes. Por lo que solo estoy destacando todos los cambios que habría hecho saber que estoy usando la unidad
de trabajo en la unidad de trabajo cuadrada para el repositorio de asignación de licencias, unidad de cuatro para el repositorio de solicitudes de licencia. Y luego cuando tenemos una operación que está aumentando los datos, hacemos un Guardar. ¿Ves eso? Ahora mientras estoy en este manejador de solicitud de creación de licencia, solo
quería señalar otro punto de falla que vi en mis pruebas y probablemente te hayas encontrado y solo quiero que lo abordemos aquí. Ahí es cuando no hay asignación porque traté de
solicitar licencia de maternidad con una empleada que no tiene licencia de maternidad. Entonces tienes dos formas de lidiar con eso. Uno, solo podrías, podrías filtrar esa lista de tipos de hojas solo en tipos de licencia que se asignan a ese usuario. Por lo que el usuario nunca sería capaz de solicitar algo para lo que no tienen asignación. Y francamente, creo que esa es una buena manera limpia de hacer a esto crea una nueva llamada de repositorio donde obtienes esas listas puntiagudas y enviaste, pero no menos importante, creo que eso es bastante fácil. Yo sin embargo, he hecho un ajuste en este manejador en el ínterin para decir obtener la asignación. Entonces recuerda que tenemos la asignación y luego calculamos la d se solicita. Y si se solicita el d, se excede, entonces agregamos un error de resultados de validación, ¿no? Bueno, lo que estoy haciendo aquí es que estoy viendo si la asignación no lo es. Entonces con la nueva versión de C Sharp, no
tienes que ver es equivalente a saber que la vacante es no, ¿verdad? Entonces si esto vuelve como nulo, entonces agregamos un error de resultado de validación para el ID de tipo de hoja, diciendo que no tienes ninguna asignación para este tipo de hoja. Entonces esa es una simple adición si otra. Puedes seguir adelante y replicar eso o podrías probarlo por tu cuenta para obtener la lista filtrada para ese usuario en particular que está a punto de solicitar licencia y solo mostrar los tipos de hojas para los que son elegibles, cualquiera que funcione. Ahora saltemos a la actualización leave request command handler, que es donde vimos los verdaderos puntos de falla que estamos tratando de abordar AHORA con la unidad de trabajo. Por lo que una vez más, inyectar sólo las unidades fueron obligadas a este manejador. Y verás que es mucho más compacto, ¿verdad? Y luego cada línea, solo hay que decir que las unidades son cuatro puntos el repositorio apropiado y punto punto el método. Sepa cuándo estamos incrementando los datos. Recuerda que dijimos si la solicitud entra con el DTO, entonces vamos adelante y hacemos nuestro mapeo llamado actualización. Y luego voy a llamar a las unidades de trabajo para ahorrar. Está bien. Posteriormente, no si fue la aprobación de solicitud de cambio y aquí fue donde vimos la falla, vamos a seguir adelante y cambiar su aprobación. Y luego si se aprobaba, entonces actualizaría la asignación. Y entonces éste funcionó, pero luego este campo, por lo que se aprobó y los de la persona estos no se adoptaron, eso causó inconsistencia. Entonces no, esta persona se habría ido de vacaciones durante 10 días y
regresaremos y veremos que sigue siendo a menudo estos y plie
roto y nadie se daría cuenta. Por lo que querremos asegurarnos de que nuestro sistema no tenga la culpa. Correcto. Por lo que actualizamos el cambio el estado de aprobación. Bien. Entonces si se aprueba, actualizamos el número de días y luego ahorramos. Entonces si esto falla, esto sucede en la base de datos. Ahora con este cambio y la unidad de dónde se introduce, realidad
es un factor más grande porque en realidad tendrás que ir a cada manejador que se ocupaba de aumentar los datos y una unidad de trabajo de inyector para probablemente cambien las referencias más antiguas a los repositorios, todos por todo el lugar. Y luego tres, asegúrate de llamar al método de ahorro de unidad de trabajo. Ahora que has hecho ese enorme factor de riesgo, ¿de acuerdo? Y sobre todo cuando se ha hecho eso al manejador de comandos tipo hoja y otros puntos de contención que surgirán son nuestras pruebas unitarias. Porque recuerda, al menos hicimos las pruebas unitarias para el manejador de comandos tipo hoja juntos y sabemos que estás cambiando la inyección, estás cambiando algo al respecto. Entonces, en realidad si compilas en ese punto, probablemente
obtendrías algunos errores en los archivos de prueba porque ya no existen ciertas cosas nulas. Eso es 12. El hecho de que la operación haya cambiado en general, necesitamos actualizar a los artistas. Empecemos con los burlones porque probablemente ahí es donde estás obteniendo el primer error de que el repo de Mach ya no existe o los chicos burlones ya no del tipo que necesita. Eso está bien. Entonces lo que he hecho es crear un nuevo archivo Mock al que llamo simulacros de unidades de trabajo. Y está siguiendo el mismo principio el humo anterior, donde solo estoy instanciando un simulacro de nuestra unidad de trabajo. Se llama obtener unidades de trabajo. Ese es un método. Y tengo simulacro, vas a w es igual a una nueva instancia de la unidad de trabajo simulada. No, tengo el tipo de hoja simulada. Déjame corregir ese repo tipo hoja simulada. Eso es lo que estábamos tratando, ¿verdad? Entonces esa es la prueba que escribimos para probar los tipos de hojas. Sepa que estoy usando la unidad de donde tengo que burlarme del repositorio dentro de la unidad de trabajo. Y ya tengo el código para burlarme de las unidades del repositorio tipo elif, lo siento, correcto, Así que ya tengo eso. Ese método no tiene que cambiar en absoluto. Está bien. Lo estamos llenando con datos de prueba y lo hemos hecho todo. No, necesito meter a este Mach en el simulacro de unidad de trabajo. Entonces todo lo que estoy haciendo aquí es ver burla. El repositorio de tipo es igual a llamar a esa clase simulada y obtener el repositorio de tipo hoja. Y luego mi aviso de configuración es que el repositorio tipo hoja devolverá ese objeto simulado. Entonces devuelvo esas simuladas unidades de trabajo. Entonces ahora en la prueba real para el manejador tipo hoja, y acabo de comentar algunas de las líneas solo para mostrarte qué exactamente he cambiado. He introducido un nuevo campo de tipo simulacro I unidades de trabajo llamado simulacro. Vas a w, w unidad de trabajo. Y luego lo he instanciado dentro
del constructor llamando a mis unidades simuladas de trabajo punto a2 unidades o tenedor. Después, todo lo demás sigue igual. No se alineen. Bueno para mí, 42, 43, donde estoy viendo que el manejador no es una nueva instancia que tome la unidad de
trabajo simulada a diferencia de la ondulación simulada ha usado previamente y ese objeto, entonces todo lo demás fluirá. Entonces al menos no lo hagas en las pruebas tenemos que decir simulacro de unidad de trabajo punto objeto, punto hoja tipo repositorio obtiene todo. Del mismo modo simulacro de unidad de trabajo punto punto repositorio lifo obtiene todo. De lo contrario, las pruebas pasarán y entonces estás bien para ir. Por lo que una vez más, las pruebas unitarias te mostrarían llenar puntos o puntos potenciales de falla en diferentes partes de tu aplicación por si acaso lo son, o pasaron por actividades masivas de refactor. Pero eso es realmente todo para esta actividad donde estamos sumando las unidades de trabajo. Espero que vean el valor en ella y seguiremos mejorando nuestra aplicación en lecciones posteriores.
38. Manejo de la terminación de Token: En esta lección, vamos a estar configurando un middleware global de manejo de excepciones para nuestra API. Entonces lo que pasa es que teníamos excepciones
personalizadas que creamos desde casi el inicio del proyecto. Hemos estado lanzando excepciones en ciertos puntos de nuestros manejadores. No obstante, no hemos dicho necesariamente la API entera que debe responder cuando se lanzan excepciones. Entonces por supuesto, querrás fallar siempre con gracia si hay un tipo de excepción, queremos enviar de vuelta un código que sea indicativo del tipo de excepción. Por ejemplo, he actualizado todos mis manejadores de actualización para lanzar también una excepción no encontrada. Entonces después de saber, déjame simplemente corregir este. Tan abierto a saber. Yo no tenía el código. Si ya tenías el código, entonces eso está bien. Eso son saludos para ti, ¿verdad? Pero estábamos lanzando excepciones de validación cuando la validación falla. Pero entonces lo que pasa si el registro que se encuentra no era teléfono, entonces queremos una excepción no encontrada. Por lo que he agregado que en cada cheque para ver si se encuentra asignación de licencia, si la licencia solicita, Eso es un barco para actualizarse su teléfono y si la licencia lo siento, el tipo de hoja, su objetivo. Si el tipo de hoja es de teléfono, simplemente
lanzamos una excepción no encontrada. ¿ Está bien? Por lo que lanzar la excepción es bastante fácil. Manejarlo es otra cosa. Por lo que ten en cuenta que no hay tramos de capturas. Sería una especie de avance dominante tratar de poner el try catch y cada uno. Entonces lo que vamos a hacer es configurar y manejar excepciones middleware a nivel API porque el controlador usa medios para llamarlo manejador, pero tampoco tenemos ninguna pista de capturas aquí, así que siempre estamos regresando, ¿de acuerdo? Pero luego hay momentos en los que se lanza la excepción y se Ok, se puede lanzar. Y en la API es literalmente solo lanzar algo de buck de respuesta aleatoria en el cliente. Queremos asegurarnos de que sepamos lo que se está lanzando. Así que adelante y crea una nueva carpeta en el proyecto API llamado middleware. Y en esa carpeta crear un archivo llamado middleware de excepción. Entonces ese es nuestro middleware de excepción cruzada. Y sólo voy a guiarte a través de lo que esto va a estar haciendo en web o detalles. Entonces tenemos una clase en ese archivo, en esa otra clase llamada detalles de error. Yo solo te estoy guiando por las partes más simples primero. Y los detalles del error solo tiene el tipo de error y un mensaje de error. Entonces al menos siempre podemos informar al cliente esto es lo que salió mal en
base a la circunstancia con la que nos enfrentamos ¿verdad? Ahora. Todo decía que tenemos dentro de la clase para middleware excepcional, tenemos campo privado de solo lectura llamado siguiente, y eso es de tipo request delegado. Por lo que instanciamos eso en el constructor. Y entonces tenemos un método llamado invocar un fregadero. Por lo que asyncTask público invocan async y toma un parámetro llamado contextos HTTP. Por lo que ya tipo de miramos lo que los contextos HTTP nos permiten hacer. Básicamente, nos permite ver la solicitud, la respuesta, todo con un flujo de trabajo completo entre cliente y servidor se almacena dentro de estos contextos HTTP. Entonces esto va a estar actuando como un interceptor, se va a tratar de ver. Se va a decir hacer la siguiente opción que se debe completar vía los contextos HTTP. Eso es básicamente lo que eso está haciendo. Ella. contextos http hacen su siguiente opción. Si hay una excepción, vamos a atraparla y entonces la manejaremos. Ahora, pasemos a cómo lo manejamos. Por lo que la excepción de manejo de tarea privada es hundir donde le
da el contexto HTTP y la excepción que fue capturada. Conoce solo estamos diciendo que queremos que una respuesta punteada sea aplicación slash JSON porque es la API. Entonces sabemos que todo lo que respondamos va a ser en forma de JSON. También estamos configurando un error interno de servidor predeterminado, código de estado
HTTP escuela está por defecto a lo que es 500. Entonces vamos a decir que el resultado es igual a, nunca
quiero serializar objetos en una nueva instancia de flecha con el mensaje de excepción. Muy bien, entonces estamos serializando todo esto en los resultados nulos cuando vamos al interruptor. Donde básicamente ver qué tipo de excepción es este, porque la excepción es el tipo de datos base. Pero entonces como hemos visto, tenemos nuestras propias excepciones. Tenemos la excepción de validación, tenemos el déjame salir la mantequilla solicita excepción. Tenemos la excepción no encontrada. Por lo que podemos dar cuenta de todos estos contabilizando por mala solicitud. No estoy contabilizando la validación. Yo. Adelante y actualiza eso. Entonces lo que estamos haciendo aquí ahora es ver decirme qué tipo de excepción es. Sé que es una excepción, pero de qué tipo fue realmente no fue tan mala petición. Una excepción de validación más bien debe su no me encuentran. En base al punto que hay que hacer es que vamos a cambiar el statu quo. Entonces es moratoria a 50, 100. Significa que si solo fue lo poco excepcional, tal vez fue en falla a nivel de base de datos, tal vez fue una falla de red que no podemos abrochar. Y cuatro, entonces definitivamente es un 500. 500 significa que es un sistema, el sistema que está usando la API, es culpa del sistema. No obstante, las malas peticiones indicarían que tienes la culpa como cliente, pero me enviaste datos de basura. Entonces les voy a decir que es una mala petición, que es una hace 400 años. Si es una excepción de validación, eso también es una especie de mala solicitud porque me enviaste pero datos, pero siempre puedes mirar a través y ver qué otro código podría o mejor para el tipo de excepción. Está bien, pero entonces siempre quieres quedarte en el rango 400 con códigos de error, ¿verdad? Entonces ahí es donde estamos. Entonces quiero decir para ti Eso está solo. Entonces este dice Pero solicitar y luego no encontrar excepción es un 40 por significado no pude encontrar lo que estás buscando. Entonces 40 para así si ninguno de estos era el caso, entonces simplemente rompemos y eso quedaría como un 500. Después vemos responder con el código de estado y regresar con el resultado. Resultado, lo que significa ese mensaje completo que formaba parte del mensaje de excepción. Entonces recuerda que cuando estamos configurando nuestras excepciones o lanzando nuestras excepciones a nuestros cazadores, siempre
estaban sentados el mensaje. Y ese mensaje es lo que se está serializando aquí. Me están enviando bokeh desató esa respuesta. Nulo si quieres que sea un poco más explícito. Porque todo lo que estamos haciendo es enviar sobre flecha con mensaje de excepción, podríamos usar nuestros detalles de error. Podría haber dicho nuevos detalles de error y luego mensaje de
error sería el mensaje y el tipo de error podría ser otra cosa. Entonces yo diría Eric Type Tool y luego probablemente sólo decir fracaso, nuestro error, lo que sea para que puedas ponerte creativo. Es decir, depende de ti lo que, una vez más, esto es lo que obtendrían en su respuesta, lo que sea que pongas ahí. Entonces un modo que hemos terminado de configurar ese middleware, necesitamos saltar al archivo de inicio para API. Y inserto de la Configurar sexual. Vamos a decirle que use el middleware. Entonces solo lo voy a hacer justo por encima de todo lo demás. No quiero decir que hasta DOT use middleware, excepción en middleware. Adelante y agrega cualquier referencia que falte. Y ahí vamos. Por lo que todos tenemos nuestro middleware tratando de atrapar globalmente y luego manejar con gracia cómo responde a cualquier cliente que sea su vocación. Solo quería volver a saltar a la implementación una vez más y tener un ajuste rápido. No sé por qué tenía si esto fuera fuera inicialmente. Entonces con los resultados para la excepción de validación, definitivamente
queremos que los errores de excepción estén yendo Buck en el cuerpo, ¿verdad? Entonces los mensajes de validación, una cosa, bien. Pero entonces queremos que los resultados sean iguales a la serialización JSON de la validación de las flechas, ¿verdad? Por lo que una vez más, tienes muchas opciones sobre cómo manejar la situación. Entonces estamos sentando el mensaje de excepción por defecto, pero lo estamos anulando en el caso del error de validación. Entonces será la lista de errores.
39. Manejo de la terminación de Token: De acuerdo, así que seguimos mejorando en nuestra aplicación, y esta vez estamos cambiando nuestro enfoque de nuevo a nuestra aplicación cliente. Por lo que aquí algunos escenarios que no hemos contabilizado, o al menos probablemente los hayamos encontrado, pero no los hemos abordado del todo. Número 1, cuando probablemente te des cuenta ya que si iniciaste sesión hace aproximadamente una hora y el cercano Buffon tu turno para usar un sistema. Están recibiendo excepciones de la API para 100 unas porque el token que está ahí, pesar de que estás asignado a la aplicación, tolkien está caducado. Entonces el cliente sube las cosas, está bien. Pero cuando intentas acceder a la API y enviar un token fijo, la AICPA lo está rechazando y la aplicación no sabe qué hacer. Por lo que probablemente estés obteniendo esas páginas de excepción. Y otra cosa es que queremos configurar tu propia página personalizada para cuando se envíe una solicitud de navegación no autorizada. Significa que eres un usuario, pero estás tratando de llegar a una página de administración. Habrías visto a MIGA el error y probablemente hayas llegado a flecha donde está intentando ir a una página llamada Acceso denegado, que es una de las páginas por defecto que no robaron en esta aplicación cliente. Entonces les voy a mostrar cómo podemos aprovechar
aún más todo el contexto HTTP, la canalización de solicitudes. Acabamos de hacerlo con el manejo de excepciones para la API y todo lo que vamos a ver en la aplicación cliente y cómo podemos manejar estos diferentes escenarios de manera global. Entonces empecemos con el middleware costal que tengo configurada. Y estoy llamando a su solicitud middleware. Algunos llamándolo solicitan el middleware porque quería sentarme entre cada solicitud de navegación que alguna vez ocurre en nuestra aplicación. Y luego al igual que vimos con la API, siempre
podemos interceptar, interrogar y luego tomar una decisión como
debe ir la palabra si cumple con ciertos criterios sobre. Pero empecemos con una carpeta llamada middleware en el MVC arriba y el archivo se llama peticiones, el middleware. Por lo que esta va a ser una clase pública que se lleve el delegado de solicitud a continuación. Y también estoy inyectando mi servicio de almacenamiento local va, recuerda ahí es donde estamos accediendo al Tolkien desde cualquier momento. Entonces seguimos adelante y los inicializamos en el constructor, y luego tenemos nuestra tarea de método, invocamos un fregadero. Entonces este método tiene un gran try-catch, ¿verdad? Ganó gran try-catch. Entonces vamos a intentarlo. Y la línea más simple sería igual que vimos en la API, sería tan simple. Trata de esperar a la siguiente subasta y luego atrapar y manejar cualquier excepción. Está bien. No obstante, antes de que sigamos adelante y permitamos que pruebe la siguiente acción, queremos hacer algunas comprobaciones. Entonces el cheque que estamos haciendo es, bueno uno, estamos consiguiendo los puntos finales. Por lo que esta línea EP representa el punto final. los contextos HTTP puntan las características, obtener la característica de extremo de IA y obtener los puntos finales, lo que significa a dónde vas, a dónde la herramienta Rosing. Entonces voy a ver, ¿tiene este extremo algún atributo de metadatos? Entonces recuerda cuando nuestros controladores, estos son básicamente atributos de metadatos, ¿verdad? Entonces, ¿tiene algún atributo de metadatos, tipo de atributo de autorización? Bueno, autorizado es de tipo autorizar atributo. Entonces estoy viendo dondequiera que estés navegando herramienta, hay un atributos autorizados que nunca controlan o son algún punto
final tiene un autor como atributo va a casa no tiene ningún usuario, no tiene ninguno. Entonces si lo hace, decir que tenemos algo, no
es nulo, entonces queremos decir,
vale, ya que este endpoint está autorizado para asegurarse que haya un Tolkien y aún más para que este token sea válido. Entonces voy a decir que el atributo de autor no es igual a nulo. O lo siento, si no es igual a nulo, entonces consígueme el almacenamiento local. Tolkien, correcto, así que ve y comprueba si existe. Y entonces también estoy viendo que es válido porque estoy asumiendo que es válido en todo momento. No obstante, si existe, necesitamos validarlo aún más alma, ¿no? Entonces estoy viendo si el Tolkien existe, entonces consigue el Tolkien real, entonces estoy usando el mango de seguridad, el manejador Tolkien. Sabemos lo que necesitamos para inyectar una declaración de uso para eso. Y luego estoy viendo Consígueme el contenido Tolkien, luego consigue la caducidad, y luego comprueba si se hace la caducidad. Está bien. Entonces si la fecha de caducidad es menor que el punto de fecha y hora 10, lo que significa que tenemos estamos mucho más allá o donde ningún pasado, cualquier hora se sentará como exploración, entonces el token no es válido. Entonces voy a decir si el token no es válido o el Tolkien no existe, y nota los signos de exclamación. Por lo que esto fácilmente podría haber sido equivale a falso, que es lo que haré para aumentar la legibilidad. Entonces si alguno de estos es falso, entonces queremos llamar a un método que creé abajo llamado sinusoides y redirigir pasando en el contexto HTTP. Por lo que viven los contextos HTTP. De este middleware, no hay problema, simplemente lo
pasamos y luego regresamos. Entonces eso significa que cualquiera que sea la opción que aquí se diga apunta a la siguiente opción. Nunca llegaremos a este si nos interceptamos en este punto. No otro que esté haciendo es si el atributo auth tiene las reglas. Por lo que en realidad podemos poner en varias filas, se
puede ver coma de administrador, esta coma que, por lo que tantas reglas como sea necesario comprobar. Pero en este caso, solo quiero asegurarme de que si los atributos del autor, como vemos aquí, se limiten a solo administradores y el usuario no esté en el rol de administrador. Entonces quiero redirigir a casa slash no autorizado. Por lo que esto es cuando estaba dispuesto al acceso negado por defecto. Por lo que solo lo estamos anulando y viendo ir a nuestra página personalizada. Por favor redirija y regrese. Entonces si el token es válido, pero no eres un administrador tratando de llegar a una ruta de administrador a la que vamos a redirigir, y ese es el final de eso. Ahora hay situaciones en las que podríamos atrapar una excepción al intentar pasar por esta operación. Una de esas situaciones sería con la API. Por lo que a veces podría haber algún problema de sincronización con el tiempo, lo que significa que podemos considerar que el Tolkien no está caducado y válido. Pero luego cuando pasa a la EPA, la EPA aún lanza una excepción viendo 40 un año no autorizados. De acuerdo, entonces en esa situación, lo que vamos a hacer es cerrar sesión y redirigir también tienen una situación similar al middleware de excepción API, donde estamos viendo la excepción. Si se trata de un tipo de excepción de API, entonces realice esa acción. De lo contrario simplemente redirigir a la página de error de barras generales de inicio, redirigir y romper. Entonces veamos lo que sucede en este Seinfeld y redirijamos. Todo lo que estamos haciendo, los estamos enviando a todos fuera del contexto http, igual que a lo que tendríamos mil millones para, uso un servicio, el tiempo de logotipos. Y luego te vamos a redirigir a la ruta para los usuarios slash login. Entonces pernos de la página de inicio de sesión y luego seguir adelante y redirigir, luego regresamos. Entonces eso es todo lo que sucede dentro de esas áreas. ¿ Todo bien? Y entonces básicamente eso siempre los hace ahí. Entonces si todo esto se salta, todo eso se salta. No hay atributo, entonces adelante y circula la siguiente solicitud. Si atrapamos una excepción, bien vamos a la página de error o estamos asumiendo si se trata de una excepción API, Senado y redireccionamiento, Por supuesto, podría
haber diferentes tipos de excepciones de la EPA son escenarios diferentes con ellos. Por lo que podría tener fácilmente otro método costal para ver si la excepción de API es de tipo. Este tipo de respuesta luego ir a este tipo de discurso porque ese objeto de excepción de EPA realmente contiene código de respuesta. Por lo que podemos obtener más bien el código de estado. Ahí vamos, podemos obtener el código de estado que se está enviando de vuelta. Entonces si son 40, 1, entonces sine Alton redirecciona. Si es tal vez 500, entonces haz esto. Entonces recuerda que teníamos configurados nuestros diferentes tipos de códigos de respuesta en la API. Entonces sabemos que podemos conseguir solicitudes de mantequilla, podemos obtener validación, podemos conseguir no teléfono, ¿verdad? Por lo que en base al tipo de código de estado que estamos esperando de la API, volverá en la excepción y luego podremos manejarlo. Entonces esa es una forma rápida y sucia de manejar tipo de lo que sucede cuando los Tolkien están vencidos o si tenemos diferentes excepciones que no somos capaces de manejar. Y a medida que veas más excepciones, por supuesto, puedes poner más capacidades de manejo en el middleware. No. Apenas rápidamente en el hogar. Algunos redireccionando a o es que estoy redirigiendo a un acceso denegado o no autorizado discurso. No es nada fondos se crea en el controlador domiciliario y nueva acción no está autorizada. Y yo sólo tengo una página que literalmente sólo dice ese texto no autorizado. Eso es todo lo que está pasando. Ahí hay jumbotron no autorizar, por lo que puedes enloquecer con tu creatividad. Encuentra un bonito PCC personalizado. No pasarás sobre la salida neta. Eso es todo lo que realmente está pasando. Entonces vamos a probar esto. Sólo voy a intentar navegar a una página que sé que no puedo conseguir demasiado mientras no estoy conectado. Y luego ves no autorizado. Está bien. En este punto, probablemente podríamos ver si hay un intento de Ambrose a una página donde hay etiqueta no autorizada y el usuario no es malo,
autenticado, luego redirigido a la página de inicio de sesión, ¿verdad? Eso tendría más sentido si estoy conectado como usuario. Y una vez que llego, solo estoy dando ideas para sostener, para controlar tu aplicación crece si trato de iniciar sesión como usuario regular. Y luego una vez más trato de llegar a la página de administración, no estoy autorizado. No obstante, puedo navegar a una página que estoy autorizado la Herramienta Bowl y estoy recibiendo un error. Entonces ni siquiera probé este correctamente y está justamente frente a ti y eso está bien. Es bueno ver que estas fallas provocarían que esta es otra excepción. Y es más que probable porque tengo la regla de auth sin el atributo del autor con más reglas en él, ¿verdad? Entonces estoy tratando de llegar a un lugar que no tiene filas en los atributos de auth. Y luego por ese fracaso está captando la excepción. Entonces ahora va a ir a la página de error de slash home, que sólo va a decir que hubo un error al intentar completar tu comando. Entonces por supuesto que eso es un arenque rojo porque ese no es realmente el tema. Estoy tratando de llegar a esa página. Está bien. No estoy autorizado. Eso se ve un poco mejor si traté de llegar a uno que crean las solicitudes. De acuerdo, así que ahí está. Por lo que siempre que haya una bandera de autorización con más filas, esto va a arrojar un error. Y eso es lo que pasa Porque se autorizan las solicitudes de licencia, pero no tiene regla de estipulación. Entonces, solo reflujo a esto rápidamente. Y esa fue una buena zona para conseguir porque inspiró unos bits de código mucho mejores y mucho más funcionales en este refactor. Entonces me deshice de algunas de las cuerdas mágicas y creo que
contabiliza mucho más situación global ya que se relaciona con las reglas, estipulaciones, ¿verdad? Inicialmente, era solo que si no eres administrador, entonces no puedes entrar. Pero entonces si tienes múltiples roles e incluso usuarios con múltiples roles, quieres asegurarte de que estás dando cuenta de todas las situaciones, ¿no? Entonces en esta situación dije si auth dot roles o el autor atribuye roles no es igual a null, hay roles en la lista. Entonces adelante y consigue el rol del usuario. Muy bien, entonces estamos consiguiendo el rol de tipo reclamo. Por supuesto que no necesitas poner una declaración de uso para esto. Y entonces obtenemos ese valor. Entonces veo si la lista de reglas no contiene esa regla. Muy bien, por lo que se podrían usar múltiples roles para asegurar endpoint. Un usuario puede tener múltiples roles. Si este usuario no tiene ningún rol y esto sólo es contabilizar a nuestro usuario con una sola regla. Entonces déjame, déjame retroceder. Esto es cuando sólo se asigna un rol a un usuario. Es posible que tengas que hacer un poco más terminado, tal vez un para cada bucle o usar algún otro método para averiguar si alguna de las reglas de los usuarios, en cualquiera de las reglas y en su lugar en los atributos, pero correcto, y todo lo que obtenemos el una regla para el usuario y comprobar si la lista de reglas sobre adolescentes ese rol del usuario. Y si no, entonces no están autorizados para esa petición en particular. Y eso es básicamente todo. Por lo que puedes jugar con esto y puedes ver que esta variable llena, pero si no escribes la cita con suficiente cuidado, podría tirar de la aplicación y renunciar a una pequeña pantalla de un error cuando realmente no hay nada malo o cuando es tu propia culpa. Por lo que quieres tener mucho cuidado cuando tienes cotización de 18 años para el middleware. Pero en realidad es muy poderoso.
40. Mejorar la Auditoría de datos: En esta lección, vamos a estar buscando mejorar la auditoría. Entonces, hasta el momento hemos implementado alguna cantidad de auditoría en nuestros
cambios de guardar donde tomamos cada entidad una vez que está fuera de la entidad de dominio base, llegamos a establecer los datos Last-Modificado y el grande creado automáticamente. No tenemos que hacer eso cada vez que estamos creando estos objetos para ser salvados, ¿verdad? Entonces lo que vamos a hacer es crear un segundo contexto DB que en realidad se apoderará de esta auditoría porque lo no
estamos haciendo en este momento es agregar los nombres
del usuario o el nombre del usuario para el creado por el último modificado por. Por lo que necesitamos una forma de conseguir que el usuario completando la acción en la base de datos automáticamente. Entonces iniciamos esta actividad con un archivo totalmente nuevo que estoy llamando contexto DB auditable. Ahora es una clase abstracta y hereda del contexto DB. Tiene un constructor que es muy similar a la escena anterior en contexto de base de datos de gestión de licencias, excepto que solo toma contexto DB, opciones, opciones, por lo que no está escrito o está en la otra, lo
habrías visto tipos como en realidad tiene mecanografía para el contexto DB. Bueno, esta vez no estamos haciendo eso, sólo
estamos tomando opciones. Muy bien, entonces tenemos nuestra propia implementación de un guardar cambios. Por lo que esta no es una tarea asíncrona virtual de anulación pública. Devolver cambios int guardar. Se necesita un parámetro llamado string username, cual estoy por defecto para ser sistema, lo que significa que si no se proporciona ningún nombre de usuario, entonces el sistema es lo que entrará en esa columna de nombre de usuario. Por lo que puedes hacer eso si lo deseas. Si tienes un defecto, de lo contrario solo puedes cumplir con ese nulo. Entonces, una vez más, esto no es una anulación. Por lo que en realidad tenemos
lo mismo para cada bucle que está
pasando por la entrada y las lesiones de
camionero cambio basado en detección para entidades de línea base. Está bien. Y luego decimos ir adelante y establecer la última fecha de modificación y la fecha agregada o la fecha de creación en cualquier momento se esté agregando una. Ahora, yo antes de proceder, quisiera filtrar más esto porque el instructor de CI está transportando todo si no está modificado,
si está desprendido todo, no
necesitamos estos cambios en las cosas atuendo no ser modificado o agregado. Entonces voy a agregar un filtro adicional a esto donde estoy viendo conseguirme esas entradas, analizarlas en entidad de dominio base. Pero donde sus estados, así q-dot state se agrega o modifica. Por lo que sólo nos interesa sentar estos campos de auditoría sobre cualquier cosa que se esté actualizando o creando. Entonces puedo saber, digamos entry dot entity dot last modified by es igual al nombre de usuario que se pasa en. Muy bien, y luego similitud, puedo ver el CreatedBy es el nombre de usuario que se pasa. Está bien, así que todo eso solo para asegurarnos de que tengamos el nombre de usuario presente. Pero después de eso vamos a ver resultado var es igual a 08 base. Por lo que BS una vez más es contexto DB. Tan basado dot save cambia asíncrono, y luego regresamos ese resultado. Ahora veamos los cambios que se requieren para los contextos DVI de gestión de licencias originales. Uno, no necesito anular, ver si cambia aquí otra vez, así que puedo quitar eso por completo. Esa es una herramienta que sé que necesita heredar de los contextos de DB auditables. Entonces es este contextos DVI está heredando del auditable,
que luego está heredando de los contextos DVI para el auditable está dando su propia versión. Ya veré si los cambios antes llamará a la base Guardar Cambios, que es cortesía de contextos DVI de todos modos. Entonces con todo eso hecho, ahora
podemos modificar nuestras unidades de trabajo. Porque recuerden, sepan que hemos implementado que
tenemos nuestro C de cambios ocurriendo aquí mismo. Y esto se llama en contexto. Con eso inyectado en, puedo bajar a mi función de guardar y puedo ver nombre de usuario es igual a los contextos HTTP accessor contextos HTTP, el usuario encuentra el primer nombre para el ID de usuario porque recuerda ahí es donde estamos almacenando el ID de usuario. Tan bueno, sí, así que solo estoy usando los tipos de reclamo personalizados dot UID. Otra razón que queremos evitar el CNS mucho extremo y conveniente y limpio que se ve, y estamos obteniendo ese valor para que podamos pasar ese nombre de usuario a este método, que luego saltaría por aquí, botas auditando cosas, y luego guardar el cambios reales al contexto DB y devolver los resultados si lo necesitamos. Entonces así se puede mejorar la auditoría. Entonces con este contexto DB auditable sentado entre la unidad de trabajo y los contextos DVI reales. Aquí hay pocas cosas que puedes hacer. Algunas personas realmente tendrían como una base de datos de auditoría real o una tabla de auditoría o un conjunto de tablas. Quieren registrar cada axón que se está llevando a cabo en contra de estas entidades, no sólo sentar estos campos, sino tal vez replicarlos a otro lugar. Todo eso podría suceder potencialmente aquí. No voy a decir todo eso podría causar que habrá algunas limitaciones. Pero he visto donde la gente realmente hace auditorías completas entre esto,
este bit de código y este bit de código, ¿verdad? Tan unidad, por lo que para se extiende sobre todo. Y luego para cada entidad que está ahí esperando ser salvada, los manipulamos. Y luego los salvamos.
41. Conclusión: Quiero decir gracias chicos por aguantar hasta el final de este curso conmigo donde no necesariamente
teníamos un sistema de gestión de licencias de EHR totalmente funcional al final del mismo. Pero hemos mirado algunas técnicas avanzadas. Sé que puedes quitarte y aplicarlo a tus rutinas diarias. Durante la duración de este curso, escribimos código que era modulo comprobable, mantenible y reutilizable, y fuimos sensibles a los principios arquitectónicos sólidos. Implementamos el mar QRS y medios a patrones. Analizamos las mejores prácticas para la separación de preocupaciones. Implementamos una API. Miramos cómo asegurarlo con autenticación JWT y aguantar para consumir eso y usar eso a nuestra ventaja en una aplicación cliente, hemos hecho tanto juntos y estoy muy una vez más agradecido por su dedicación y su apoyo y tienes alguna sugerencia. Siéntase libre de dejarlos en el cuadro de sugerencias. Y siempre estoy abierto a la retroalimentación. Gracias una vez más y ten uno genial.