微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

asp.net-mvc-3 – 使用AutoMapper携带元数据查看模型的技术

我使用AutoMapper将我的域对象映射到我的视图模型。我在我的域层中有元数据,我想继承到视图层并进入ModelMetadata。 (这个元数据不是UI逻辑,而是为我的观点提供了必要的信息)。

现在,我的解决方案是使用单独的MetadataProvider(独立于ASP.NET MVC),并使用约定通过AssociatedMetadataProvider将相关元数据应用于ModelMetadata对象。这种方法的问题是,当我使用AutoMapping绑定模型元数据时,我必须测试相同的约定,并且似乎应该有一种方法使其更正确。任何人都可以推荐一个更好的方式来完成这个?

解决方法

我使用下面的方法自动将数据注释从我的实体复制到我的视图模型。这确保像StringLength和required值这样的实体对于entity / viewmodel始终是相同的。

它使用Automapper配置工作,因此只要AutoMapper设置正确,视图模型上属性的命名方式就不同了。

您需要创建一个自定义的ModelValidatorProvider和定制的ModelMetadataProvider来使其工作。我的记忆为什么有点雾,但我相信服务器和客户端验证工作以及您根据元数据执行的任何其他格式(例如所需字段旁边的星号)都是如此。

注意:我已经简化了我的代码,因为我在下面添加了它,所以可能会有一些小问题。

元数据提供者

public class MetadataProvider : DataAnnotationsModelMetadataProvider
{        
    private IConfigurationProvider _mapper;

    public MetadataProvider(IConfigurationProvider mapper)
    {           
        _mapper = mapper;
    }

    protected override System.Web.Mvc.ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes,Type containerType,Func<object> modelAccessor,Type modelType,string propertyName)
    {           
        //Grab attributes from the entity columns and copy them to the view model
        var mappedAttributes = _mapper.GetMappedAttributes(containerType,propertyName,attributes);

        return base.CreateMetadata(mappedAttributes,containerType,modelAccessor,modelType,propertyName);

}
}

验证器提供者

public class ValidatorProvider : DataAnnotationsModelValidatorProvider
{
    private IConfigurationProvider _mapper;

    public ValidatorProvider(IConfigurationProvider mapper) 
    {
        _mapper = mapper;
    }

    protected override System.Collections.Generic.IEnumerable<ModelValidator> GetValidators(System.Web.Mvc.ModelMetadata Metadata,ControllerContext context,IEnumerable<Attribute> attributes)
    {   
        var mappedAttributes = _mapper.GetMappedAttributes(Metadata.ContainerType,Metadata.PropertyName,attributes);
        return base.GetValidators(Metadata,context,mappedAttributes);
    }
}

辅导方法参考上述2类

public static IEnumerable<Attribute> GetMappedAttributes(this IConfigurationProvider mapper,Type sourceType,string propertyName,IEnumerable<Attribute> existingAttributes)
{
    if (sourceType != null)
    {
        foreach (var typeMap in mapper.GetAllTypeMaps().Where(i => i.sourceType == sourceType))
        {
            foreach (var propertyMap in typeMap.GetPropertyMaps())
            {
                if (propertyMap.IsIgnored() || propertyMap.sourceMember == null)
                    continue;

                if (propertyMap.sourceMember.Name == propertyName)
                {
                    foreach (ValidationAttribute attribute in propertyMap.DestinationProperty.GetCustomAttributes(typeof(ValidationAttribute),true))
                    {
                        if (!existingAttributes.Any(i => i.GetType() == attribute.GetType()))
                            yield return attribute;
                    }
                }
            }
        }
    }

    if (existingAttributes != null)
    {
        foreach (var attribute in existingAttributes)
        {
            yield return attribute;
        }
    }

}

其他注释

>如果您使用依赖注入,请确保您的容器尚未替换内置元数据提供程序或验证程序提供程序。在我的情况下,我使用的是Ninject.MVC3包,它在创建内核后绑定了其中一个,然后我不得不重新绑定,所以我的类实际上被使用。我得到例外,只有被允许添加一次,花了大部分时间来跟踪它。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


这篇文章主要讲解了“WPF如何实现带筛选功能的DataGrid”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“WPF...
本篇内容介绍了“基于WPF如何实现3D画廊动画效果”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这...
Some samples are below for ASP.Net web form controls:(from http://www.visualize.uk.com/resources/asp
问题描述: 对于未定义为 System.String 的列,唯一有效的值是(引发异常)。 For columns not defined as System.String, the only vali
最近用到了CalendarExtender,结果不知道为什么发生了错位,如图在Google和百度上找了很久,中文的文章里面似乎只提到了如何本地化(就是显示中文的月份)以及怎么解决被下拉框挡住的问题,谈
ASP.NET 2.0 page lifecyle ASP.NET 2.0 event sequence changed a lot since 1.1. Here is the order: App
静态声明: &#39; Style=&quot;position: relative&quot; AppendDataBoundItems=&quot;True&quot;&gt; (无 或 空 或
以下内容是从网络上搜集资料,然后整理而来的。不当之处,请不吝指教。(The following were from network, and edited by myself. Thanks in a
Imports System Imports System.Reflection Namespace DotNetNuke &#39;*********************************
Ok so you have all seen them: “8 million tools for web development”, “5 gagillion tools that if you