Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 21 de noviembre de 2017
ASP.NET Core MVC Hace unos días veíamos lo sencillo que resultaba personalizar las plantillas de generación de código para proyectos MVC desde Visual Studio, e incluso cómo crear plantillas específicas para proyectos.

Pero dado que siempre hablábamos de Visual Studio, es lógico preguntarse si posible conseguir exactamente lo mismo desde la línea de comandos o, llevándolo al extremo, en entornos no Windows como Linux o Mac, así que en este post veremos cómo conseguirlo.

Vamos a partir de una aplicación Web ASP.NET Core vacía, creada desde la línea de comandos, y veremos la secuencia utilizando una distribución Debian de Linux en la que hemos instalado el SDK de .NET Core siguiendo las instrucciones de la documentación oficial, pero sería exactamente igual hacerlo en Windows o Mac.

Creación de la aplicación usando el CLI

Primero, creamos la aplicación:
jmaguilar@Debian-JM:~$ mkdir MyApp

jmaguilar@Debian-JM:~$ cd MyApp/

jmaguilar@Debian-JM:~/MyApp$ dotnet new web
The template "ASP.NET Core Empty" was created successfully.
This template contains technologies from parties other than Microsoft, 
   see https://aka.ms/template-3pn for details.

Processing post-creation actions...
Running 'dotnet restore' on /home/jmaguilar/MyApp/MyApp.csproj...
  Restoring packages for /home/jmaguilar/MyApp/MyApp.csproj...
  Generating MSBuild file /home/jmaguilar/MyApp/obj/MyApp.csproj.nuget.g.props.
  Generating MSBuild file /home/jmaguilar/MyApp/obj/MyApp.csproj.nuget.g.targets.
  Restore completed in 47.98 sec for /home/jmaguilar/MyApp/MyApp.csproj.

Restore succeeded.
jmaguilar@Debian-JM:~/MyApp$ _
De esta forma, ya tenemos la aplicación ASP.NET Core creada, y lista para ser ejecutada con “dotnet run“.

Generación de código con  aspnet-codegenerator

Como sabemos, el CLI de .NET Core es extensible: se le pueden añadir comandos, distribuidos en forma de paquetes NuGet, para dotar al SDK de nuevas funcionalidades.

Centrándonos en el caso que nos ocupa, es el paquete Microsoft.VisualStudio.Web.CodeGeneration.Tools el que nos trae el comando “dotnet aspnet-codegenerator“, que nos permite generar elementos de aplicaciones ASP.NET Core MVC, como controladores, vistas, etc. Es el equivalente en el CLI a las opciones de scaffolding de Visual Studio.

Fijaos que, a pesar de que el desafortunado nombre del paquete pueda indicar lo contrario, los componentes que contienen no están ligados en absoluto a Visual Studio. Se trata de elementos totalmente multiplataforma, y compatibles con el CLI.

Por tanto, para poder utilizar este comando lo primero que necesitamos es añadir a nuestro proyecto una referencia hacia este paquete NuGet, algo que conseguimos insertando la siguiente porción de código en el archivo .csproj.
<ItemGroup>
   <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
</ItemGroup>
Nota: hay varias plantillas de proyecto (por ejemplo, la plantilla de proyectos MVC) que incluyen ya esta referencia en el .csproj, por lo que no sería necesario introducirla de nuevo.
En cualquier caso, una vez hemos asegurado que el archivo de proyecto incluye estas líneas y hemos restaurado los paquetes desde Nuget (“dotnet restore), ya casi estamos en disposición de utilizar el comando “dotnet aspnet-codegenerator“. Aún existe otra dependencia por satisfacer, que podemos descubrir si intentamos ejecutar este comando:
jmaguilar@Debian-JM:~/MyApp$ dotnet aspnet-codegenerator
Building project ...

Unhandled Exception: System.InvalidOperationException: Please add Microsoft.VisualStudio.Web.CodeGeneration.Design package to the project as a NuGet package reference.
   at Microsoft.VisualStudio.Web.CodeGeneration.Tools.Program...
   [...]

jmaguilar@Debian-JM:~/MyApp$ _
Por tanto, para que funcione, debemos también añadir una referencia al paquete NuGet Microsoft.VisualStudio.Web.CodeGeneration.Design, algo que podemos conseguir editando manualmente el archivo .csproj, o bien utilizando el comando “dotnet add package“:
jmaguilar@Debian-JM:~/MyApp$ dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design

  Writing /tmp/tmpcWoCPi.tmp
info : Adding PackageReference for package 'Microsoft.VisualStudio.Web.CodeGeneration.Design' 
       into project '/home/jmaguilar/MyApp/MyApp.csproj'.
log  : Restoring packages for /home/jmaguilar/MyApp/MyApp.csproj...
info :   GET https://api.nuget.org/v3-flatcontainer/microsoft.visualstudio.web.codegeneration.design/index.json
info :   OK https://api.nuget.org/v3-flatcontainer/microsoft.visualstudio.web.codegeneration.design/index.json 117ms
info : Package 'Microsoft.VisualStudio.Web.CodeGeneration.Design' is compatible with all the specified frameworks in project '/home/jmaguilar/MyApp/MyApp.csproj'.
info : PackageReference for package 'Microsoft.VisualStudio.Web.CodeGeneration.Design' version '2.0.0' added to file '/home/jmaguilar/MyApp/MyApp.csproj'.

jmaguilar@Debian-JM:~/MyApp$ dotnet restore
  Restoring packages for /home/jmaguilar/MyApp/MyApp.csproj...
  Restore completed in 3.38 sec for /home/jmaguilar/MyApp/MyApp.csproj.
  Restore completed in 44.48 ms for /home/jmaguilar/MyApp/MyApp.csproj.

jmaguilar@Debian-JM:~/MyApp$ _
Como en el caso anterior, este paquete no es nada específico para Visual Studio, por lo que podemos utilizarlo en cualquier entorno.

Generación de código desde el CLI

A partir de este momento ya estamos en disposición de ejecutar el comando, donde podremos obtener una idea de qué podemos conseguir con él, y cómo utilizarlo:
jmaguilar@Debian-JM:~/MyApp$ dotnet aspnet-codegenerator

Building project ...
Usage: dotnet aspnet-codegenerator --project [projectname] [code generator name]

Code Generators:
  view
  razorpage
  controller
  area

Try dotnet aspnet-codegenerator --project [projectname] [code generator name] -? for help about specific code generator.
RunTime 00:00:09.71

jmaguilar@Debian-JM:~/MyApp$ _
Como se puede observar, existen distintos generadores de código que nos ayudarán a añadir a nuestro proyecto vistas, páginas Razor, controladores y áreas. La siguiente secuencia de comandos muestra cómo utilizar el comando para crear un controlador vacío llamado HomeController en la carpeta /Controllers del proyecto:
jmaguilar@Debian-JM:~/MyApp$ dotnet aspnet-codegenerator controller -name HomeController -outDir Controllers
Building project ...
Finding the generator 'controller'...
Running the generator 'controller'...
Added Controller : '/Controllers/HomeController.cs'.
RunTime 00:00:24.95

jmaguilar@Debian-JM:~/MyApp$ cd Controllers

jmaguilar@Debian-JM:~/MyApp/Controllers$ ls
HomeController.cs

jmaguilar@Debian-JM:~/MyApp/Controllers$ cat HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace MyApp.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}
jmaguilar@Debian-JM:~/MyApp/Controllers$ _
El comando dotnet aspnet-codegenerator permite, además, añadir parámetros para cada tipo de componente que permiten afinar en detalles y contenidos del código generado. Por ejemplo, en caso de añadir controladores es posible indicar aspectos como su nombre, si queremos generar acciones estilo ReST sobre una clase del Modelo o acciones tipo CRUD, el contexto de datos a utilizar, si las acciones deben ser asíncronas, si generamos también las vistas, características de éstas, etc. Podemos ver todas estas opciones si invocamos la ayuda mediante el comando “dotnet aspnet-generator controller -h“:
jmaguilar@Debian-JM:~/MyApp$ dotnet aspnet-codegenerator controller -h

Usage: aspnet-codegenerator [arguments] [options]

Arguments:
  generator  Name of the generator. Check available generators below.

Options:
  -p|--project             Path to .csproj file in the project.
  -n|--nuget-package-dir
  -c|--configuration       Configuration for the project (Possible values: Debug/ Release)
  -tfm|--target-framework  Target Framework to use. (Short folder name of the tfm. eg. net46)
  -b|--build-base-path
  --no-build

Selected Code Generator: controller

Generator Options:
  --controllerName|-name              : Name of the controller
  --useAsyncActions|-async            : Switch to indicate whether to generate async controller actions
  --noViews|-nv                       : Switch to indicate whether to generate CRUD views
  --restWithNoViews|-api              : Specify this switch to generate a Controller with REST
                                        style API, noViews is assumed and any view related
                                        options are ignored
  --readWriteActions|-actions         : Specify this switch to generate Controller with
                                        read/write actions when a Model class is not used
  --model|-m                          : Model class to use
  --dataContext|-dc                   : DbContext class to use
  --referenceScriptLibraries|-scripts : Switch to specify whether to reference script libraries
                                        in the generated views
  --layout|-l                         : Custom Layout page to use
  --useDefaultLayout|-udl             : Switch to specify that default layout should be used 
                                        for the views
  --force|-f                          : Use this option to overwrite existing files
  --relativeFolderPath|-outDir        : Specify the relative output folder path from project
                                        where the file needs to be generated, if not specified, 
                                        file will be generated in the project folder
  --controllerNamespace|-namespace    : Specify the name of the namespace to use 
                                        for the generated controller


RunTime 00:00:04.75
jmaguilar@Debian-JM:~/MyApp$ _
Por ejemplo, mediante el siguiente comando generamos el controlador TestController de un API ReST asíncrono para la entidad MyModel del proyecto, utilizando el contexto de datos MyContext de Entity Framework Core (ojo, tanto la entidad como el contexto deben existir previamente):
jmaguilar@Debian-JM:~/MyApp$ dotnet aspnet-codegenerator controller -name TestController -api -m MyModel -dc MyContext -async -outDir Controllers 

Building project ...
Finding the generator 'controller'...
Running the generator 'controller'...
Attempting to compile the application in memory.
Attempting to figure out the EntityFramework metadata for the model and DbContext: 'MyModel'
Added Controller : '/Controllers/TestController.cs'.
RunTime 00:00:18.06

jmaguilar@Debian-JM:~/MyApp$ _
El resultado generado (parcial) en el archivo Controllers/TestController.cs es el siguiente:
namespace MyApp.Controllers
{
    [Produces("application/json")]
    [Route("api/Test")]
    public class TestController : Controller
    {
        private readonly MyContext _context;

        public Test(MyContext context)
        {
            _context = context;
        }

        // GET: api/Test
        [HttpGet]
        public IEnumerable<MyModel> GetMyModels()
        {
            return _context.MyModels;
        }

        [...]
    }
}    
De la misma forma que hemos generado controladores, podemos también generar vistas vacías, o las clásicas vistas de CRUD para listar, crear, editar o ver entidades. Por ejemplo, el siguiente comando genera una vista de edición para la entidad MyModel en el archivo “Editar.cshtml” de la carpeta actual:
jmaguilar@Debian-JM:~/MyApp$ dotnet aspnet-codegenerator view Editar Edit  -m MyModel

Building project ...
Finding the generator 'view'...
Running the generator 'view'...
Added View : /Editar.cshtml
RunTime 00:00:17.27
jmaguilar@Debian-JM:~/MyApp$ _

¿Y si queremos usar plantillas personalizadas para generar esos elementos?

Pues simplemente demos seguir las instrucciones que ya describimos en el post anterior. Resumidamente, basta con copiar las plantillas proporcionadas por defecto a una carpeta llamada Templates en nuestro proyecto.

Por defecto las plantillas proporcionadas por el framework se encuentran en las siguientes carpetas, según el sistema operativo que utilicemos:
  • En Linux (Debian), en el directorio /usr/share/dotnet/sdk/NuGetFallbackFolder/microsoft.visualstudio.web.codegenerators.mvc/2.0.0/Templates
  • En Windows, en la carpeta %programfiles%\dotnet\sdk\NuGetFallbackFolder\microsoft.visualstudio.web.codegenerators.mvc\2.0.0\Templates.
  • En Mac… ni idea, la verdad… supongo que la ruta se parecerá a la de Linux, pero no tengo un Mac para comprobarlo ;D
Una vez copiados estos archivos a nuestro proyecto, podemos modificar los archivos .cshtml a nuestro, y el comando “dotnet aspnet-codegenerator” siempre los utilizará como plantillas para la generación de código.

Publicado en Variable not found.

Aún no hay comentarios, ¡sé el primero!