Preguntas para entrevista de .NET

En una entrevista de trabajo para un cargo en .NET pueden hacerte alguna de las siguientes preguntas:

  • ¿Qué es NET? 01:47
  • ¿.NET es OpenSource?
  • ¿Qué es CLR?
  • ¿Qué es MSIL?
  • ¿Qué es Garbage Collection?
  • ¿Que es LINQ?
  • ¿Overloading o Overriding?
  • ¿Const o Read Only?
  • ¿Struct o Class?
  • ¿Qué es Asp Net?
  • ¿Que és MVC?
  • ¿Xamarin o Net MAUI?
  • ¿Qué es Blazor?
  • ¿Qué es Nuget?
  • ¿Entity Framework o EF Core?

Cada una de las respuestas en el siguiente video

Modo dark en SQL Server Management

Microsoft SQL Server Management Studio (SSMS) es el IDE oficial para este motor.

En su versión 19.3 aún seguimos contando solo con dos temas disponibles: Blue o Light

Pero sabías que existe un tercero: Un modo dark

Habilitando modo dark

Para ello debes editar el archivo ssms.pkgundef

De acuerdo a la versión puedes encontrarlo en:

SMS 2016:

C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn\ManagementStudio

SSMS 17:

C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Binn\ManagementStudio

SSMS 18:

C:\Program Files (x86)\Microsoft SQL Server Management Studio 18\Common7\IDE

SSMS 19:

C:\Program Files (x86)\Microsoft SQL Server Management Studio 19\Common7\IDE

SSMS 20:

C:\Program Files (x86)\Microsoft SQL Server Management Studio 20\Common7\IDE

En mi caso:

Deberemos editarlo con permisos de «Administrador». En mi caso usaré NOTEPAD++

Lo que haremos iremos al final y buscaremos la línea de «DarkTheme» y lo comentaremos agregando dos barras «//»

Aquí el antes y el después:

Guardamos y ya estamos listo para disfrutar nuestro nuevo tema, vamos a options (settings)

Como conectar tu dispositivo con visual studio de forma inalámbrica

Lo primer que debes ubicar es la herramienta ADB.

En mi caso se encuentra en «C:\Program Files (x86)\Android\android-sdk\platform-tools»

el comando es ADB PAIR y ADB CONNECT

.\adb.exe pair 172.0.2.30:45151

.\adb.exe connect 172.0.2.30:45757

El ip es el dispositivo móvil que quieres conectar. Para ello debes hacer el siguiente procedimiento en tu celular o tablet

1- Ingresar al modo desarrollador

2-Activar depuración inalámbrica

3-Elegir emparejar con código

4-Aquí veras el IP y puerto que deberás usar con adb pair

5-Luego deberás tomar el ip y puerto que figura en la pantalla principal para usar con adb connect

Una vez finalizado ya podrás elegir tu dispositivo desde Visual Studio

error MSB3030: No se pudo copiar el archivo

Desde hace tiempo que vengo trabajando con Net MAUI para el desarrollo de aplicaciones móviles. Pero algunos paquetes de Google Firebase han empezado a presentar inconvenientes, sobre todo cuando trabajas con iOs. Por ello decidí empezar a probar la versión Net 8.0 preview con VS2022 preview. Algo tan simple puede volverse un dolor de cabeza…

C:\Program Files\dotnet\sdk\8.0.100-rc.1.23455.8\Microsoft.Common.CurrentVersion.targets(4879,5): error MSB3030: No se
pudo copiar el archivo "D:\NUGET\xamarin.firebase.ios.cloudfirestore\8.10.0.3\lib\net6.0-ios15.4\Firebase.CloudFirestor
e.resources\grpcpp.xcframework\ios-arm64_x86_64-simulator\grpcpp.framework\PrivateHeaders\src\core\ext\upb-generated\en
voy\config\filter\network\http_connection_manager\v2\http_connection_manager.upb.h" porque no se encontró. [D:\source\r
epos\globalassistgroup\metroin.app-trabajador\metroin.app-trabajador\metroin.app-trabajador.csproj::TargetFramework=net
8.0-ios]
Error Could not find a part of the path 'C:\Users\vivek.nuget\packages\xamarin.firebase.ios.core\8.10.0.1\lib\xamarinios10\Firebase.Core.resources\GoogleUtilitiesComponents.xcframework\ios-arm64_i386_x86_64-simulator\GoogleUtilitiesComponents.framework\PrivateHeaders\GULCCComponentContainerInternal.h'.

¡

¿Porqué ocurre?

Al parecer por el largo de la ruta que se genera dinámicamente, la cuál no es soportado en Windows.

Solución:

Acortar la ruta. Para ello podemos modificar dos paramétros

  • Ruta de los paquetes nugets
  • Habilitar que Windows maneje rutas largas

Ruta de paquetes nugets

Debemos editar las variables de entorno y agregar dos nuevas entradas

Largo de rutas en windows

Debes crear un registro en Regedit

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem]
"LongPathsEnabled"=dword:00000001

Maximum Path Length Limitation – Win32 apps | Microsoft Learn

¿Me cuentas si te funcionó?

AMI Commands List

AMI es la interface que tiene disponible Asterisk para permitir la integración con sistemas externos.

En esta ocasión te dejo el listado completo en Asterisk 18 de comandos disponibles para interactuar con tu PBX

AbsoluteTimeout Set absolute timeout.
AGI Add an AGI command to execute by
AOCMessage Generate an Advice of Charge mess
Atxfer Attended transfer.
BlindTransfer Blind transfer channel(s) to the
Bridge Bridge two channels already in th
BridgeDestroy Destroy a bridge.
BridgeInfo Get information about a bridge.
BridgeKick Kick a channel from a bridge.
BridgeList Get a list of bridges in the syst
BridgeTechnologyList List available bridging technolog
BridgeTechnologySuspend Suspend a bridging technology.
BridgeTechnologyUnsuspend Unsuspend a bridging technology.
CancelAtxfer Cancel an attended transfer.
Challenge Generate Challenge for MD5 Auth.
ChangeMonitor Change monitoring filename of a c
Command Execute Asterisk CLI Command.
ConfbridgeKick Kick a Confbridge user.
ConfbridgeList List participants in a conference
ConfbridgeListRooms List active conferences.
ConfbridgeLock Lock a Confbridge conference.
ConfbridgeMute Mute a Confbridge user.
ConfbridgeSetSingleVideoSrc Set a conference user as the sing
ConfbridgeStartRecord Start recording a Confbridge conf
ConfbridgeStopRecord Stop recording a Confbridge confe
ConfbridgeUnlock Unlock a Confbridge conference.
ConfbridgeUnmute Unmute a Confbridge user.
ControlPlayback Control the playback of a file be
CoreSettings Show PBX core settings (version e
CoreShowChannels List currently active channels.
CoreStatus Show PBX core status variables.
CreateConfig Creates an empty file in the conf
DAHDIDialOffhook Dial over DAHDI channel while off
DAHDIDNDoff Toggle DAHDI channel Do Not Distu
DAHDIDNDon Toggle DAHDI channel Do Not Distu
DAHDIHangup Hangup DAHDI Channel.
DAHDIRestart Fully Restart DAHDI channels (ter
DAHDIShowChannels Show status of DAHDI channels.
DAHDITransfer Transfer DAHDI Channel.
DBDel Delete DB entry.
DBDelTree Delete DB Tree.
DBGet Get DB Entry.
DBGetTree Get DB entries, optionally at a p
DBPut Put DB entry.
DeviceStateList List the current known device sta
DialplanExtensionAdd Add an extension to the dialplan
DialplanExtensionRemove Remove an extension from the dial
Events Control Event Flow.
ExtensionState Check Extension Status.
ExtensionStateList List the current known extension
FAXSession Responds with a detailed descript
FAXSessions Lists active FAX sessions
FAXStats Responds with fax statistics
Filter Dynamically add filters for the c
G729LicenseList G.729 License List
G729LicenseStatus G.729 License Status
GetConfig Retrieve configuration.
GetConfigJSON Retrieve configuration (JSON form
Getvar Gets a channel variable or functi
Hangup Hangup channel.
IAXnetstats Show IAX Netstats.
IAXpeerlist List IAX Peers.
IAXpeers List IAX peers.
IAXregistry Show IAX registrations.
ListCategories List categories in configuration
ListCommands List available manager commands.
LocalOptimizeAway Optimize away a local channel whe
LoggerRotate Reload and rotate the Asterisk lo
Login Login Manager.
Logoff Logoff Manager.
MailboxCount Check Mailbox Message Count.
MailboxStatus Check mailbox.
MeetmeList List participants in a conference
MeetmeListRooms List active conferences.
MeetmeMute Mute a Meetme user.
MeetmeUnmute Unmute a Meetme user.
MessageSend Send an out of call message to an
MessageSendInfo
MixMonitor Record a call and mix the audio d
MixMonitorMute Mute / unMute a Mixmonitor record
ModuleCheck Check if module is loaded.
ModuleLoad Module management.
Monitor Monitor a channel.
MuteAudio Mute an audio stream.
Originate Originate a call.
Park Park a channel.
ParkedCalls List parked calls.
Parkinglots Get a list of parking lots
PauseMonitor Pause monitoring of a channel.
Ping Keepalive command.
PJSIPCallIDToChannel
PJSIPNotify Send a NOTIFY to either an endpoi
PJSIPQualify Qualify a chan_pjsip endpoint.
PJSIPRegister Register an outbound registration
PJSIPShowAors Lists PJSIP AORs.
PJSIPShowAuths Lists PJSIP Auths.
PJSIPShowContacts Lists PJSIP Contacts.
PJSIPShowEndpoint Detail listing of an endpoint and
PJSIPShowEndpoints Lists PJSIP endpoints.
PJSIPShowRegistrationInboundContactStatuses Lists ContactStatuses for PJSIP i
PJSIPShowRegistrationsInbound Lists PJSIP inbound registrations
PJSIPShowRegistrationsOutbound Lists PJSIP outbound registration
PJSIPShowResourceLists Displays settings for configured
PJSIPShowSubscriptionsInbound Lists subscriptions.
PJSIPShowSubscriptionsOutbound Lists subscriptions.
PJSIPUnregister Unregister an outbound registrati
PlayDTMF Play DTMF signal on a specific ch
PlayMF Play MF digit on a specific chann
PresenceState Check Presence State
PresenceStateList List the current known presence s
PRIDebugFileSet Set the file used for PRI debug m
PRIDebugFileUnset Disables file output for PRI debu
PRIDebugSet Set PRI debug levels for a span
PRIShowSpans Show status of PRI spans.
QueueAdd Add interface to queue.
QueueChangePriorityCaller Change priority of a caller on qu
QueueLog Adds custom entry in queue_log.
QueueMemberRingInUse Set the ringinuse value for a que
QueuePause Makes a queue member temporarily
QueuePenalty Set the penalty for a queue membe
QueueReload Reload a queue, queues, or any su
QueueRemove Remove interface from queue.
QueueReset Reset queue statistics.
QueueRule Queue Rules.
QueueStatus Show queue status.
QueueSummary Show queue summary.
QueueWithdrawCaller Request to withdraw a caller from
Redirect Redirect (transfer) a call.
Reload Send a reload event.
SendText Sends a text message to channel.
Setvar Sets a channel variable or functi
ShowDialPlan Show dialplan contexts and extens
SorceryMemoryCacheExpire Expire (remove) ALL objects from
SorceryMemoryCacheExpireObject Expire (remove) an object from a
SorceryMemoryCachePopulate Expire all objects from a memory
SorceryMemoryCacheStale Marks ALL objects in a sorcery me
SorceryMemoryCacheStaleObject Mark an object in a sorcery memor
Status List channel status.
StopMixMonitor Stop recording a call through Mix
StopMonitor Stop monitoring a channel.
UnpauseMonitor Unpause monitoring of a channel.
UpdateConfig Update basic configuration.
UserEvent Send an arbitrary event.
VoicemailRefresh Tell Asterisk to poll mailboxes f
VoicemailUsersList List All Voicemail User Informati
VoicemailUserStatus Show the status of given voicemai
WaitEvent Wait for an event to occur.

mover tu wsl a otro disco

Desde que apareció WSL en Windows ya no tuve la necesidad de tener que tener una VM con alguna distro de Linux.

Si no sabes lo que es WSL (Windows Subsystem for linux) aquí te dejo la documentación oficial Instalación de WSL | Microsoft Learn

Pero en pocas palabras es la capacidad que tiene Windows (desde win 10) de exponer el acceso al procesador a través de una capa controlada, pudiendo tener otro mini sistema operativo corriendo a la par. A diferencia de la emulación, aquí lo que se intenta es que ambas sistemas operativos puedan acceder al procesado, y ahorrar recursos sobre todo.

En mi caso, para acceder a servidores y programar, suele tener dos distros:

  • Ubuntu 22.04 (WSL 2)
  • Debian (WSL)

Ambos con dos versiones diferentes de WSL. Esto es debido a que el performance del disco en la versión 2 de WSL, se vio afectada, y por otro lado hay problemas de compatibilidad, aún con la versión dos.

El espacio destinado a cada una es de unas 10gigas, y aveces resulta cómodo tenerlas en algún disco diferente. Por ello hoy veremos el proceso para mover las mismas a otra ubicación.

Listar las distro instaladas:

wsl --list -v

Con este simple comando podrás ver que distro tienes disponibles y que versión son.

Detener la distro a mover.

En mi caso la de Debian

wsl -t Debian

Exportar la distro

wsl --export Debian "D:\WSL\debian.tar"

Esta parte demora unos minutos dependiende del tamaña de tu distro. En mi caso la voy a mover al disco D:, a una carpeta denominada WSL

Desregistrar la distro

wsl --unregister Debian

Actualizamos el registro, eliminando distro actual, y luego volviendo a crear pero con la nueva ubicación

Importar la distro

wsl --import Debian "D:\WSL\Debian" "D:\WSL\debian.tar"

Ya estamos llegando a su fin. Aquí solamente le decimos que queremos importar nuestro distro, indicando el nombre de la misma, la ubicación en donde va a quedar, y el donde en donde esta el backup.

Vale aclarar que con este proceso no pierdes nada de lo que tengas en tu distro, como así también el perfil que tengas en tu terminal ya configurado.

Espero que te sea útil. En mi caso no demoró mas de 5 min todo el proceso.

Failed to execute operation: No such file or directory

¿Porque un systemctl enable myservice.service da este error?

Hoy es unos de esos días donde algo tan simple deja de funcionar. Te pongo en contexto: Un worker service creado en .NET 7.0 encargado de interactuar con un servicio de telefónia Asteriks y una API de .NET

Este servicio funciona correctamente en el servidor linux que cuenta con CentOS y una distro de «FreePBX». Por lo que se decidió pasar a servicio la ejecución del mismo.

Para ello, de acuerdo a la documentación de .NET tan solo con el siguiente archivo de texto es suficiente:

Host ASP.NET Core on Linux with Nginx | Microsoft Learn

[Unit]
Description=Example .NET Web API App running on Linux
After=network.target

[Service]
WorkingDirectory=/var/ami
ExecStart=/usr/bin/dotnet /var/ami/WorkerServiceAMI.dll
Restart=always

Restart service after 10 seconds if the dotnet service crashes:

RestartSec=10

KillSignal=SIGINT
SyslogIdentifier=dotnet-ami
User=root
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target

Una vez generado el mismo tan solo al ejecutar systemctl enable myservice.service debería funcionar pero recibía constantemente este error:

Failed to execute operation: No such file or directory

Luego de romperme la cabeza y no encontrar la solución en Google me puse analizar el porque no encontraba el archivo. Y entendí lo siguiente: Systemctl es parte del administrador de servicios del sistema, por lo tanto busca los archivos de forma predeterminada en /etc/systemd/system o /usr/lib/systemd/system.

Solución:

Copia el archivo dentro de esa ubicación y asunto arreglado.

Espero que te sirva este dato.

Maui con Mysql

Sino sábes lo que es net MAUI te dejo un video donde está bien explicado.

La historia corta es que es el framework de Microsoft para desarrollar aplicaciones móviles nativas para iOs, Android, MacOs y Windows.

En caso de que requieras persistencias historicamente se ha trabajado siempre con el motor SQLLite de forma local. Pero si quieres algo más robutos te conviene buscar un motor de bases de datos como PostgreSQL, MySQL, MSSQl, etc.

Pero la cuestión aquí es: «Puedo conectarme directamente a MySQL desde Net MAUI?

La respuesta corta es: «No, Lamentablemente no es posible». El problema está en la forma en que se realiza la encriptación de la conexión al motor, y el sistema operativo que la intenta hacer, por ejemplo Android.

Tuve varias horas cacharreando con el asunto, y cada paso que avanzaba, se compensaba con dos mas de retroceso.

¿Porque lo intente hacer?

A fines educativo, ya que no es la manera correcta.

¿Como deberías hacerlo?

Siempre a través de un servicio web (WebService Rest Ful). Es la mejor alternativa ya que simplemente con un cliente web (http client) podrás realizar la integración de una manera standarizada.

No uses Newtonsoft

Seguramente para serializar / deserializar tus json ocupas la librería externa de Newtonsoft Json.NET – Newtonsoft

Esta librería nos acompaña desde el 2011, y durante todo el furor de .NET framework fue la mejor alternativa que teníamos disponible.

Luego con la aparición de Net Core (2016) y su enfoque en el rendimiento estaba claro que había que tener algo nativo para el trabajo con JSON ya que es un estándar a la hora de pasar información entre servicios web del tipo WebAPI. Por ello surgió la clase nativa System.Text.Json. De manera muy tímida fue adquiriendo mayor funcionalidad, pero sobre todo un mejor rendimiento en performance frente a su competidor mas estable.

Al día de hoy tenemos Net 7.0 y en la puerta Net 8.0 que será liberado en noviembre del 2023. Por ello me propuse realizar una comparativa para ver que tan cierto era esto de que System.Text.Json es 100% más rapido que NetwtonSoft.

Aquí te dejo el video y los resultados te sorprenderán

Para ello haremos un #benchmark usando los frameworks de #net7 y #net8.

Mover la tempDB en MS SQL Server

Errores como esto puede significar que algo anda mal con tu TempDB

The operating system returned error 1117(No se puede realizar la solicitud por un error del dispositivo de E/S.) to SQL Server during a write at offset 0x0000003f840000 in file 'C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\MSSQL\DATA\tempdb.mdf'

Se puede tratar de indagar el motivo, pero en esta ocasión, vamos a mover directamente la TempDB que está en producción. Quedó actualmente en el disco del sistema operativo (mal ahí), y llegó la hora de llevarla a un nuevo disco preparado para todas las E/S que estaba recibiendo.

Aquí te explico en esta tutorial como realizar el proceso

Paso 1: Creamos la nueva ubicación: En mi caso H:\TempDB

Paso 2: Con la siguiente consulta podremos generar el script necesario para poder moverlo directamente

declare @destiny as varchar(20)
set @destiny = 'G:\TempDB\'
SELECT 'ALTER DATABASE tempdb MODIFY FILE (NAME = [' + t.name + '],'
	+ ' FILENAME = ''H:\TempDb\' + t.name
	+ CASE WHEN t.type = 1 THEN '.ldf' ELSE '.mdf' END
	+ ''');' as command
FROM sys.master_files t
WHERE t.database_id = DB_ID(N'tempdb');

En mi caso 5 archivos MDF (4 en la posición anterior, y 1 que ya había movido a fines de prueba) y un 1 archivo LDF

La respuesta ya te indica que en el próximo reinicio ocuparán la nueva ubicación

Procedemos a reiniciar y deberías ya tener la TempDB movida de ubicación