Uncategorized

Añadir configuración .net6

Hay varias formas, esta es cómoda y eficaz:

NuGet package Microsoft.Extensions.Configuration.Json 6.0.0

En el program.cs creamos un nuevo ConfigurationManager y le añadimos nuestro archivo de configuración con AddJsonFile.

Para acceder a secciones conocidas como ConnectionString basta con usar las extensiones .GetConnectionString(«csname»)

Para la configuración lo más cómodo es tener una clase con las mismas propiedades «Properties.cs» en este ejemplo y enlazar con el método bind.

–>program.cs

using Microsoft.Extensions.Configuration;


ConfigurationManager configurationBuilder = new();
configurationBuilder.AddJsonFile("appsettings.json");
string cs = configurationBuilder.GetConnectionString("csName");
Properties config = new();
configurationBuilder.GetSection("Settings").Bind(config);
Console.WriteLine(config.Cantidad.ToString() + config.Color + cs);

–>appsettings.json

{
  "ConnectionStrings": {
    "csName": "Server=.\\sql2019;Database=db_dev_fotero;User ..."
  },
  "Settings": {
    "Color": "rojo",
    "Cantidad": 12
  }
}
Anuncio publicitario
Uncategorized

Configurar Identity en nuevo proyecto

Program.cs

builder.Services.AddDefaultIdentity<IdentityUser>(options =>
    {
        options.SignIn.RequireConfirmedAccount = false;
        options.Password.RequireDigit = false;
        options.Password.RequiredLength = 4;
        options.Password.RequireNonAlphanumeric = false;
        options.Password.RequireUppercase = false;
        options.Password.RequireLowercase = false;
        options.Password.RequireDigit = false;
    })
    .AddEntityFrameworkStores<ApplicationDbContext>();

Validadores de vista–>es necesario scaffold de Identity/Pages

Install-Package Microsoft.VisualStudio.Web.CodeGeneration.Design

Instalar herramientas de codegeneration:

dotnet tool update -g dotnet-aspnet-codegenerator

dotnet aspnet-codegenerator identity

Uncategorized

Checkbox Switch Button Razor

BS6: el mismo código para check normal, sólo cambia form-switch en el div contenedor

<div class="col-auto text-end form-check form-switch">
    <input id="checkPositive" type="checkbox" class="form-check-input" @bind="ShowNuevoFabricante"/>
    <label class="form-check-label" for="checkPositive"> Nuevo</label>
</div>

Para que se visualice como un switch necesitamos:

  • crear un div que lo contenga como custom-control custom-switch
  • Crear una label con el atributo for (aunque no se quiera poner nada, es imprescindible crearla con nbsp dentro)
  • Aplicar la clase custom-control-input

En código funciona como un checkbox normal, se puede enlazar con una propiedad y detectar cambios en el SET

<div class="col-4">
   <p class="formLabel">Ocultar Negativos</p>
   <div class="custom-control custom-switch" >
      <input id="checkPositive" type="checkbox" class="custom-control-input"    @bind="ViewOnlyPositiveTrend" />
      <label class="custom-control-label" for="checkPositive"> Modificar</label>
   </div>
</div>
bool ViewOnlyPositiveTrend
{
   get
   {
       return _viewOnlyPositiveTrend;
   }
   set
   {
      _viewOnlyPositiveTrend = value;
      RefreshFromMemory();
   }
}
Uncategorized

Formularios con botón externo

En Blazor es muy sencillo usar botones externos en lugar de un submit de formulario ya que el model enlazado está disponible en servidor igualmente.

No obstante, si usamos esta opción nos perdemos las validaciones html5 del formulario, atributo required, max-min…… La alternativa es que el botón sea sólo un submit y el evento servidor lo llame el formulario en el onsubmit. Si el botón está en el formulario esto ya es automático, pero si está fuera debemos configurar la propiedad form del botón.

<form id="frmModalDocumental" @onsubmit="SaveLimiteDocumental">
                <SelectMarea EnableEdit=true required></SelectMarea>
                <SelectEspeciePesca EnableEdit=true required></SelectEspeciePesca>
                <input type="number" min="1" max="1000" required />
</form>

<button type="submit" form="frmModalDocumental">Guardar</button>
Desarrollo

Deconstrucción de Tuplas

Método ligero para devolver varios valores y asignarlos a variables:

        public void HazCosas()
        {
            int i;
            DateTime d;
            (i, _, d) = GetTuple();
        }
        private (int, string, DateTime) GetTuple()
        {
            return (2, "valor", DateTime.Now);
        }

Puede crearse una función que devuelve varios parámetros y recogerlos de forma individual, pudiendo además no recoger todos gracias al operador de descarte.

Es evidente que el abuso de tuplas en lugar de modelar los objetos que queremos devolver empeora la legibilidad del código, pero tiene su utilidad.

Blazor, Desarrollo

Añadir EF a un proyecto de 6.0

Instalar nuggets:

Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.Design
Install-Package Microsoft.EntityFrameworkCore.SqlServer

ACTUALIZA Data Entity Tools

dotnet tool update --global dotnet-ef

Crear DataContext desde consola de proyecto:

dotnet ef dbcontext scaffold "Server=.\SQL2019;Initial Catalog=NombreDB;Integrated Security=True;Connection Timeout=30;TrustServerCertificate=true;" Microsoft.EntityFrameworkCore.SqlServer --data-annotations --context NombreContexto--context-dir EF --output-dir EF --force

Compila, y ya está listo para añadir al contenedor de dependencias:

builder.Services.AddDbContextFactory<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
Blazor, Desarrollo

Enlace bidireccional de parámetro a componente

Hay dos formas básicas:

  • Usando bind-nombre del parámetro
  • Usando la combinación de unir el parámetro y subscribirse al evento de cambio.
<p>@ID</p>
<p>@ID2</p>
<form>
    <SelectIdearia @bind-Valor=ID ></SelectIdearia>
    <SelectIdearia Valor=ID2 ValorChanged=OnChange></SelectIdearia>
    <button>OK</button>
</form>

Normalmente la opción con bind es más cómoda, pero si se necesita actualizar algo en cuanto el valor cambia puede sernos útil la segunda.

public Guid ID { get; set; }
public Guid ID2 { get; set; }
public void OnChange(Guid args)=>ID2 = args;

La elección del nombre del evento no es libre, debe nombrarse como ParametroChanged para que funcione correctametne la sintaxis con @bind

La sintaxis en el emisor del evento para declaración e invocación es así:

[Parameter]
public EventCallback<Guid> KeyChanged { get; set; }

KeyChanged.InvokeAsync(value);
Blazor, Desarrollo

Componente con plantilla

Ejemplo sencillo de como crear componentes con plantilla, esto es, componentes que aceptan como parámetro su contenido

@using System.Diagnostics.CodeAnalysis
@if (ModalHeader != null)
{
    <div class="modal-header">
        @ModalHeader
    </div>
}
<div class="modal-body">
    @ModalBody
</div>
@if (ModalFooter != null)
{
    <div class="modal-footer">
        @ModalFooter
    </div>
}
@code {
    [Parameter, AllowNull]
    public RenderFragment? ModalHeader { get; set; }
    [Parameter]
    public RenderFragment ModalBody { get; set; } = null!;
    [Parameter, AllowNull]
    public RenderFragment? ModalFooter { get; set; }

  }

La forma de usar este componente sería algo así:

<Modal>
    <ModalHeader>
        <h4>Hola</h4>
    </ModalHeader>
    <ModalBody>
        <form>
            <input />
        </form>
    </ModalBody>
</Modal>

Muy interesante el uso avanzado, puede ponerse como componente genérico y que cada fragmento acepte un parámetro. El ejemplo de la página oficial de Microsoft es muy explicativo:

https://docs.microsoft.com/en-us/aspnet/core/blazor/components/templated-components?view=aspnetcore-6.0