Vista de MVC fuertemente tipada y propiedades de configuración del lado del servidor antes de enviar a capas inferiores?

StackOverflow https://stackoverflow.com/questions/7389635

  •  29-10-2019
  •  | 
  •  

Pregunta

Tengo una aplicación en capas que envía comandos a la capa de negocios (en realidad, la aplicación se basa en marco NCQRS, pero no creo que sea importante aquí).

Un comando se ve así:

public class RegisterUserCommand : CommandBase
{
    public string UserName { get; set; }
    public string Email{ get; set; }
    public DateTime RegistrationDate { get; set; }
    public string ApiKey {get; set;} // edit
}

No hay lógica en esta clase, solo datos.

Quiero que los usuarios escriban su nombre de usuario, correo electrónico y quiero que el sistema use la fecha actual para crear el comando.

¿Qué es lo mejor entre?

  1. Cree una vista fuertemente escrita basada en el registrouserCommand, luego inyecte la fecha y la clave API justo antes de enviarla a la capa de negocios.

  2. Cree una clase RegisterUserviewModel, cree la vista con esta clase y cree el objeto de comando basado en la entrada de la vista.

Escribí el siguiente código (para la solución n ° 2):

public class RegisterController : Controller
{
    //
    // GET: /Register/

    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(RegisterUserViewModel registrationData)
    {

        var service = NcqrsEnvironment.Get<ICommandService>();
        service.Execute(
            new RegisterUserCommand
            {
                RegistrationDate = DateTime.UtcNow,
                Email= registrationData.Email,
                UserName= registrationData.Name,
                ApiKey = "KeyFromConfigSpecificToCaller" // edit
            }
            );

        return View();
    }


    public class RegisterUserViewModel
    {
        [Required]
        [StringLength(16)]
        public string Name { get; set; }
        [Required]
        [StringLength(64)]
        public string Email{ get; set; }
    }
}

Este código está funcionando ... pero me pregunto si elijo la forma correcta ...

Gracias por los consejos

Editar Como la fecha y hora parece causar malentendidos, agregué otra propiedad "apikey", que también debe establecerse del lado del servidor, desde la capa web (no desde la capa de comando)

Editar 2 Pruebe la sugerencia de ERIK e implemente la primera solución que imaginé:

[HttpPost]
public ActionResult Index(RegisterUserCommand registrationCommand)
{

    var service = NcqrsEnvironment.Get<ICommandService>();
    registrationCommand.RegistrationDate = DateTime.UtcNow;
    registrationCommand.ApiKey = "KeyFromConfigSpecificToCaller";
    service.Execute(
        registrationCommand
        );

    return View();
}

... Es aceptable ?

¿Fue útil?

Solución

Creo que estaría mejor con la opción #2, donde tendría un Modelo View y un comando separado. Si bien puede parecer redundante (hasta cierto punto), sus comandos son realmente mensajes de su servidor web a su manejador de comandos. Es posible que esos mensajes no se formateen igual que su Modelo View, ni deberían serlo. Y si está utilizando NCQRS tal como está, debería mapear sus comandos a sus métodos y constructores AR.

Si bien puede ahorrarle un poco de tiempo, creo que se enciende para modelar su dominio después de sus modelos de visión, y ese no debería ser el caso. Sus modelos de vista deben ser un reflejo de lo que su usuario experimenta y ve; Su dominio debe ser un reflejo de las reglas y el conocimiento de su negocio, y no siempre se reflejan en su opinión.

Puede parecer un poco más de trabajo ahora, pero hágase un favor y mantenga sus comandos separados de sus modelos de vista. Te lo agradecerás más tarde.

Espero que esto ayude. ¡Buena suerte!

Otros consejos

Recomendaría poner esto en el constructor de la clase RegistrusUscommand. De esa manera, el comportamiento predeterminado siempre es establecerlo en Datetime.utcnow, y si necesita configurarlo en algo explícitamente, puede agregarlo al inicializador de objeto. Esto también ayudará en escenarios en los que está utilizando esta clase en otras partes de su proyecto, y se olvida de establecer el registro de la fecha explícitamente.

public class RegisterUserCommand : CommandBase
{
    public string UserName { get; set; }
    public string Email{ get; set; }
    public DateTime RegistrationDate { get; set; }

    public RegisterUserCommand()
    {
        RegistrationDate = DateTime.UtcNow;
    }
}

Y el controlador

public class RegisterController : Controller
{
    //
    // GET: /Register/

    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(RegisterUserViewModel registrationData)
    {

        var service = NcqrsEnvironment.Get<ICommandService>();
        service.Execute(
            new RegisterUserCommand
            {
                Email= registrationData.Email,
                OpenIdIdentifier = registrationData.OpenIdIdentifier
            }
            );

        return View();
    }


    public class RegisterUserViewModel
    {
        [Required]
        [StringLength(16)]
        public string Name { get; set; }
        [Required]
        [StringLength(64)]
        public string Email{ get; set; }
    }
}

Usaría el número 1 y usaría el system.componentModel.DataAnnotations.Metadatatype para validación.

Creé un ejemplo (respuesta) para otra pregunta Aquí.

Esto le permite mantener su modelo en otra biblioteca, validar los campos y mostrar los campos como lo haría con clases internas/privadas con DataNoTations. No soy un gran admirador de crear una clase completamente separada para una vista que no tiene valor adicional al tener que organizar los datos a otra clase. (Si tuviera valores adicionales como valores de lista desplegable o valores predeterminados, entonces creo que tendría sentido).

En vez de

[HttpPost]
public ActionResult Index(RegisterUserViewModel registrationData)
{

    var service = NcqrsEnvironment.Get<ICommandService>();
    service.Execute(
        new RegisterUserCommand
        {
            RegistrationDate = DateTime.UtcNow,
            Email= registrationData.Email,
            UserName= registrationData.Name,
            ApiKey = "KeyFromConfigSpecificToCaller" // edit
        }
        );

    return View();
}

Tu puedes tener

[HttpPost]
public ActionResult Index(RegisterUserCommand registrationData)
{

    var service = NcqrsEnvironment.Get<ICommandService>();

    registrationData.ApiKey = "KeyFromConfigSpecificToCaller";

    service.Execute(registrationData);

    return View();
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top