view Agendas/trunk/src/Agendas.Web/CustomModelMetadataProvider/DataAnnotationAndConventionModelMetadataProvider.cs @ 292:1408ac17cb64

Patrocinadores: Faltaba aplicar seguridad a la Api de Patrocinadores.
author juanjose.montesdeocaarbos
date Thu, 09 Feb 2012 08:40:38 -0300
parents 8b0c62c255cd
children
line wrap: on
line source

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web.Mvc;

namespace AltNetHispano.Agendas.Web.CustomModelMetadataProvider
{
	public class DataAnnotationAndConventionModelMetadataProvider : DataAnnotationsModelMetadataProvider
	{
		private readonly IResolverByConvention _resolverByConvention;
		private List<Attribute> _attributeList;

		public DataAnnotationAndConventionModelMetadataProvider(IResolverByConvention resolverByConvention)
		{
			_resolverByConvention = resolverByConvention;
		}

		protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType,
		                                                Func<object> modelAccessor, Type modelType, string propertyName)
		{
			_attributeList = new List<Attribute>(attributes);

			var modelMetadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);

			if (propertyName != null)
			{
				// Si no hay displayName asignado, lo buscamos entre los recursos
				//	Primero lo buscarmos por el Assembly FullName y el propertyName
				//	Si no lo encuentra, buscamos por el propertyName unicamente
				if (string.IsNullOrWhiteSpace(modelMetadata.DisplayName))
				{
					if (containerType != null && containerType.FullName != null)
						modelMetadata.DisplayName =
							_resolverByConvention.GetDisplayName(string.Format("{0}{1}", containerType.FullName.Replace(".", string.Empty),
							                                                   propertyName));
				}
				if (string.IsNullOrWhiteSpace(modelMetadata.DisplayName))
					modelMetadata.DisplayName = _resolverByConvention.GetDisplayName(propertyName);

				// Si no hay description asignado, lo buscamos entre los recursos
				//	Primero lo buscarmos por el Assembly FullName y el propertyName
				//	Si no lo encuentra, buscamos por el propertyName unicamente
				if (string.IsNullOrWhiteSpace(modelMetadata.Description))
				{
					if (containerType != null && containerType.FullName != null)
						modelMetadata.Description =
							_resolverByConvention.GetDescription(string.Format("{0}{1}", containerType.FullName.Replace(".", string.Empty),
							                                                   propertyName));
				}
				if (string.IsNullOrWhiteSpace(modelMetadata.Description))
					modelMetadata.Description = _resolverByConvention.GetDescription(propertyName);

				// Auto UIHint por property name. 
				// TODO: Sería ideal chequear si existe el template antes de asignarlo, ¿cómo?
				if (string.IsNullOrWhiteSpace(modelMetadata.TemplateHint))
					modelMetadata.TemplateHint = propertyName;

				// Para cada validador sin texto asignado, tomamos asignamos los valores para ser buscados
				// entre los recursos
				var validators = _attributeList.OfType<ValidationAttribute>();
				foreach (var validator in validators)
				{
					if (string.IsNullOrWhiteSpace(validator.ErrorMessage) &&
					    string.IsNullOrWhiteSpace(validator.ErrorMessageResourceName))
					{
						var resourceName = propertyName + validator.GetType().Name;
						if (resourceName.EndsWith("Attribute"))
							resourceName = resourceName.Substring(0, resourceName.Length - 9);
						var resourceType = validator.ErrorMessageResourceType ?? _resolverByConvention.ResourceType;
						var prop = resourceType.GetProperty(resourceName);
						if (prop != null)
						{
							validator.ErrorMessageResourceType = resourceType;
							validator.ErrorMessageResourceName = resourceName;
						}
					}
				}
			}

			return modelMetadata;
		}
	}
}