Artículo anterior:
ASP.NET MVC. ModelValidatorProvider personalizado (I) - Creando el proyecto de prueba
Tras crear el proyecto de prueba en este artículo vamos a ver cómo crear un proveedor de validadores personalizado de forma que podamos incluir validaciones en función del usuario autenticado en la aplicación.
Para crear el proveedor de validaciones deberemos crear una clase que herede de la clase abstracta
System.Web.Mvc.ModelValidatorProvider. Esta clase declara un único método
GetValidators que devuelve una lista de objetos
ModelValidator.
public abstract class ModelValidatorProvider
{
protected ModelValidatorProvider();
public abstract IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context);
}
Así que voy a crear en una nueva carpeta
Infrastructure una nueva clase
ValidatorProvider que herede de la clase
ModelValidatorProvider.
El objetivo es que el proveedor devuelva una nueva validación para limitar el campo
Precio de la clase
SolicitudPedido en función del usuario conectado y, si el usuario no es "Jefe", hacer obligatorio el campo
Motivo.
Para comprobar si debemos devolver los validadores el método
GetValidators recibe dos parámetros:
- Un objeto ModelMetadata con los metadatos del elemento a validar. Para saber si el elemento a validar se corresponde con las propiedades que buscamos podemos comprobar la propiedad Container que devuelve el objeto al que pertenece la propiedad y que deberá ser del tipo SolicitudPedido, y la propiedad PropertyName que devuelve el nombre de la propiedad a validar.
- Un objeto ControllerContext con el contexto del controlador. A través de este objeto podremos obtener, por ejemplo, la identidad del usuario actual.
Para crear el validador a devolver cada atributo del namespace DataAnnotations tiene su correspondiente clase con sufijo Adapter que genera el validador a partir de los metadatos del elemento, el objeto de contexto del controlador y una instancia del atributo correspondiente.
using CustomModelValidatorProvider.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
namespace CustomModelValidatorProvider.Infrastructure
{
public class ValidatorProvider: ModelValidatorProvider
{
public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
{
List<ModelValidator> validators = new List<ModelValidator>();
if (metadata.Container is SolicitudPedido)
{
switch (metadata.PropertyName)
{
case "Precio":
double precioMaximo = 100;
if (context.HttpContext.User.Identity.Name == "Jefe")
precioMaximo = 1000;
RangeAttribute range = new RangeAttribute(0.01, precioMaximo);
validators.Add(new RangeAttributeAdapter(metadata, context, range));
break;
case "Motivo":
if (context.HttpContext.User.Identity.Name != "Jefe")
validators.Add(new RequiredAttributeAdapter(metadata, context, new RequiredAttribute()));
break;
}
}
return validators;
}
}
}
Imports System.Web.Mvc
Imports System.ComponentModel.DataAnnotations
Public Class ValidatorProvider
Inherits ModelValidatorProvider
Public Overrides Function GetValidators(metadata As ModelMetadata, context As ControllerContext) As IEnumerable(Of ModelValidator)
Dim validators As New List(Of ModelValidator)
If TypeOf metadata.Container Is SolicitudPedido Then
Select Case metadata.PropertyName
Case "Precio"
Dim precioMaximo As Double = 100
If context.HttpContext.User.Identity.Name = "Jefe" Then
precioMaximo = 1000
End If
Dim range As New RangeAttribute(0.01, precioMaximo)
validators.Add(New RangeAttributeAdapter(metadata, context, range))
Case "Motivo"
If context.HttpContext.User.Identity.Name <> "Jefe" Then
validators.Add(New RequiredAttributeAdapter(metadata, context, New RequiredAttribute()))
End If
End Select
End If
Return validators
End Function
End Class
Por último únicamente quedaría registrar el proveedor en la aplicación. El framework de MVC proporciona una clase estática
ModelValidatorProviders con una propiedad
Providers que contiene los proveedores de validaciones de la aplicación.
En el evento
Application_Start del archivo
Global.asax le añadiré una instancia del nuevo proveedor a la colección.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
ModelValidatorProviders.Providers.Add(
new CustomModelValidatorProvider.Infrastructure.ValidatorProvider());
}
Protected Sub Application_Start()
AreaRegistration.RegisterAllAreas()
RouteConfig.RegisterRoutes(RouteTable.Routes)
ModelValidatorProviders.Providers.Add(New ValidatorProvider())
End Sub
Ahora si arrancamos de nuevo la aplicación podemos comprobar que las validaciones del formulario de solicitud son diferentes dependiendo del usuario con el que nos validemos:
El código
Puedes descargar el código de ejemplo de:
No hay comentarios:
Publicar un comentario