我有一个视图模型,它有一个int StateID字段和一个string StateName字段,如下所示:
public class DepartmentViewModel : BaseViewModel, IModelWithId
{
    // only show in edit mode
    public int StateId { get; set; }
    // only show in display mode
    public string StateName { get; set; }
}我有一个使用DisplayForModel的只读视图和一个使用EditorForModel的更新视图。我希望DisplayForModel视图显示StateName属性,而EditorForModel视图使用StateID属性(我实际上是基于此呈现一个下拉列表)。
我还没有弄清楚如何装饰我的视图模型属性来创建这个行为。
发布于 2010-06-03 02:10:56
我想要一个更通用的解决方案,所以我创建了一个新属性:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class RenderModeAttribute : Attribute
{
    public RenderMode RenderMode { get; set; }
    public RenderModeAttribute(RenderMode renderMode)
    {
        RenderMode = renderMode;
    }
}
public enum RenderMode
{
    Any,
    EditModeOnly,
    DisplayModeOnly
}并在我的自定义DataAnnotationsModelMetadataProvider中包含了以下代码:
var renderModeAttribute = attributes.OfType<RenderModeAttribute>();
if (renderModeAttribute.Any())
{
    var renderMode = renderModeAttribute.First().RenderMode;
    switch (renderMode)
    {
        case RenderMode.DisplayModeOnly:
            metadata.ShowForDisplay = true;
            metadata.ShowForEdit = false;
            break;
        case RenderMode.EditModeOnly:
            metadata.ShowForDisplay = false;
            metadata.ShowForEdit = true;
            break;
    }
}这样我就可以这样装饰我的模型了:
public class DepartmentViewModel    
{     
    [RenderMode(RenderMode.EditModeOnly)]   
    public int StateId { get; set; }     
    [RenderMode(RenderMode.DisplayModeOnly)]    
    public string StateName { get; set; }     
} 发布于 2011-12-06 15:36:21
对CodeGrue的回答的评论。
改为使该属性继承IMetadataAware。这样你就不需要构建自己的DataAnnotationsModelMetadataProvider了。
新属性将如下所示:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class RenderModeAttribute : Attribute, IMetadataAware
{
    public RenderMode RenderMode { get; set; }
    public RenderModeAttribute(RenderMode renderMode)
    {
        RenderMode = renderMode;
    }
    public void OnMetadataCreated(ModelMetadata metadata)
    {
        switch (RenderMode)
        {
            case RenderMode.DisplayModeOnly:
                metadata.ShowForDisplay = true;
                metadata.ShowForEdit = false;
                break;
            case RenderMode.EditModeOnly:
                metadata.ShowForDisplay = false;
                metadata.ShowForEdit = true;
                break;
            case RenderMode.None:
                metadata.ShowForDisplay = false;
                metadata.ShowForEdit = false;
                break;
        }
    }
}
public enum RenderMode
{
    Any,
    EditModeOnly,
    DisplayModeOnly
}发布于 2011-03-03 02:51:33
这是我的自定义提供程序,我添加了一个None呈现模式
public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
    protected override ModelMetadata CreateMetadata(System.Collections.Generic.IEnumerable<System.Attribute> attributes, System.Type containerType, System.Func<object> modelAccessor, System.Type modelType, string propertyName)
    {
        var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
        var renderModeAttribute = attributes.OfType<RenderModeAttribute>();
        if (renderModeAttribute.Any())
        {
            var renderMode = renderModeAttribute.First().RenderMode;
            switch (renderMode)
            {
                case RenderMode.DisplayModeOnly:
                    metadata.ShowForDisplay = true;
                    metadata.ShowForEdit = false;
                    break;
                case RenderMode.EditModeOnly:
                    metadata.ShowForDisplay = false;
                    metadata.ShowForEdit = true;
                    break;
                case RenderMode.None:
                    metadata.ShowForDisplay = false;
                    metadata.ShowForEdit = false;
                    break;
            }
        } 
        return metadata;
    }
}https://stackoverflow.com/questions/2959041
复制相似问题