view Agendas/trunk/src/Agendas.Web/ModelMetadataWithDefaultsProvider.asax.cs @ 83:7e9ffde4022d

Implementando DataAnnotation desde recursos y por convención
author nelopauselli
date Tue, 24 May 2011 21:37:06 -0300
parents
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
{
	public class ModelMetadataWithDefaultsProvider : ModelMetadataProvider
	{
		private readonly DataAnnotationsModelMetadataProvider _base;

		public ModelMetadataWithDefaultsProvider(IModelMetadataResolver modelMetadataResolver)
		{
			_base = new DataAnnotationsModelMetadataProviderWithAttributes(modelMetadataResolver);
		}

		public override IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType)
		{
			return _base.GetMetadataForProperties(container, containerType);
		}

		public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName)
		{
			var modelMetadata = _base.GetMetadataForProperty(modelAccessor, containerType, propertyName);
			return modelMetadata;
		}

		public override ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType)
		{
			return _base.GetMetadataForType(modelAccessor, modelType);
		}
	}

	public class DataAnnotationsModelMetadataProviderWithAttributes : DataAnnotationsModelMetadataProvider
	{
		private readonly IModelMetadataResolver _modelMetadataResolver;
		private List<Attribute> _attributeList;

		public DataAnnotationsModelMetadataProviderWithAttributes(IModelMetadataResolver modelMetadataResolver)
		{
			_modelMetadataResolver = modelMetadataResolver;
		}

		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)
			{
				if (string.IsNullOrWhiteSpace(modelMetadata.DisplayName))
					modelMetadata.DisplayName = _modelMetadataResolver.GetDisplayName(propertyName);

				if (string.IsNullOrWhiteSpace(modelMetadata.Description))
					modelMetadata.Description = _modelMetadataResolver.GetDescription(propertyName);

				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 ?? _modelMetadataResolver.ResourceType;
						var prop = resourceType.GetProperty(resourceName);
						if (prop != null)
						{
							validator.ErrorMessageResourceType = resourceType;
							validator.ErrorMessageResourceName = resourceName;
						}
					}
				}
			}

			return modelMetadata;
		}
	}

	public interface IModelMetadataResolver
	{
		string GetDisplayName(string propertyName);
		string GetDescription(string propertyName);
		Type ResourceType { get; }
	}

	public class ModelMetadataLocalizable<T> : IModelMetadataResolver
	{
		public string GetDisplayName(string propertyName)
		{
			return SearchResource(propertyName);
		}

		public string GetDescription(string propertyName)
		{
			return SearchResource(propertyName + "Description");
		}

		public Type ResourceType
		{
			get { return typeof(T); }
		}

		private static string SearchResource(string resourceName)
		{
			string displayName = null;
			var resourceType = typeof(T);
			var prop = resourceType.GetProperty(resourceName);
			if (prop != null)
			{
				var value = prop.GetValue(resourceType, null);
				displayName = value != null ? value.ToString() : resourceName;
			}
			return displayName;
		}

	}
}