在MVC2中的EditorForModel与DisplayForModel模式中显示不同的字段

Cod*_*rue 10 asp.net-mvc editorformodel

我有一个viewmodel,它有一个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; }
}
Run Code Online (Sandbox Code Playgroud)

我有一个使用的只读视图和使用DisplayForModel的更新视图EditorForModel.我希望DisplayForModel视图显示StateName属性,EditorForModel视图使用StateID属性(我实际上是基于此呈现下拉列表).

我无法弄清楚如何装饰我的viewmodel属性来创建此行为.

Bri*_*get 17

对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
}
Run Code Online (Sandbox Code Playgroud)


Cod*_*rue 14

我想要一个更通用的解决方案,所以我创建了一个新属性:

[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
}
Run Code Online (Sandbox Code Playgroud)

并在我的自定义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;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我可以这样装饰我的模型:

public class DepartmentViewModel    
{     
    [RenderMode(RenderMode.EditModeOnly)]   
    public int StateId { get; set; }     

    [RenderMode(RenderMode.DisplayModeOnly)]    
    public string StateName { get; set; }     
} 
Run Code Online (Sandbox Code Playgroud)

  • 感谢您分享您的解决方案.如果您能详细说明第二个代码片段需要去哪里(我假设我们需要覆盖CreateMetadata并将其放在那里?)以及如何在创建后注册我们的自定义DataAnnotationsModelMetadataProvider,这将是有用的. (2认同)