根据条件动态渲染带星号的MVC标签

时间:2015-12-16 19:51:33

标签: c# asp.net-mvc asp.net-mvc-4 html-helper required

我在MVc项目中工作。我必须显示所需字段的星号(*)符号,但我的字段不是必需的,它可能需要一些情况,可能不需要某些情况。

我的员工视图模型将是

public class EmployeeViewModel
    {
        public string Name { get; set; }

        public string Email { get; set; }

        [RequiredExtendAttribute("Manager", 121)]
        [RequiredExtendAttribute("Developer", 4)]
        public string FeedBack { get; set; }
    }

在这里,我为反馈属性添加了RequiredExtendAttribute,这意味着,当登录用户是经理并且他的经验是121时,反馈字段将是必需的,对于开发人员来说也是如此,他的经验是4。

我正在验证以下字段,

 public class RequiredExtendAttribute : RequiredAttribute, IMetadataAware
    {
        string _role;
        int _experience;

        public RequiredExtendAttribute(string role, int experience)
        {
            _role = role;
            _experience = experience;
        }

        public void OnMetadataCreated(ModelMetadata metadata)
        {
            metadata.AdditionalValues["Role"] = _role;
            metadata.AdditionalValues["Experience"] = _experience;
        }

        public override bool IsValid(object value)
        {
            if(_role == "Manager" && _experience > 120 && value == null ) // _experience in months
            {
                return false;
            }
            else if(_role == "Developer" && _experience < 6 && value == null )
            {
                return false;
            }

            return true;
        }
    }

这里我使用IMetadataAware接口来存储属性元数据中的角色和体验值,这样我就可以读取相同的值来使用*符号呈现标签。

我已经创建了如下的html助手类。

public static IHtmlString RequiredLabelFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
        {
            var metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);

            string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
            string labelText = metaData.DisplayName ?? metaData.PropertyName ?? htmlFieldName.Split('.').Last();

            string _role = string.Empty;
            int _experience = 0;

            if (metaData.AdditionalValues.ContainsKey("Role"))
            {
                _role = metaData.AdditionalValues["Role"] as string;
            }
            if (metaData.AdditionalValues.ContainsKey("Experience"))
            {
                _experience = Convert.ToInt32(metaData.AdditionalValues["Experience"]);
            }

            if ((_role == "Manager" && _experience > 120) || (_role == "Developer" && _experience < 6))
            {
                labelText += "<span class=\"red\">*</span>";
            }

            if (String.IsNullOrEmpty(labelText))
                return MvcHtmlString.Empty;

            var label = new TagBuilder("label");
            label.Attributes.Add("for", helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));

            label.InnerHtml = labelText;
            return MvcHtmlString.Create(label.ToString());
        }

我作为开发人员登录,经验为3.我的问题是metaData.AdditionalValues["Role"]此行始终返回Manager而不是Developer。如何做到这一点,感谢您的帮助。

谢谢

1 个答案:

答案 0 :(得分:0)

我建议您为模型添加更多属性,并建议检查是否需要

public bool IsRequired
{
    get
    {
        Role.Equals("Manager") && Experience == 121 ||
        Role.Equals("Developer") && Experience == 4
    }
}

然后使用RequiredIf

[RequiredIf("IsRequired", true, ErrorMessage = "Feedback is Required!")]
public string FeedBack { get; set; }

您的模型应如下所示:

public class EmployeeViewModel
{
    public string Name { get; set; }

    public string Email { get; set; }

    [RequiredIf("IsRequired", true, ErrorMessage = "Feedback is Required!")]
    public string FeedBack { get; set; }

    public string Role {get; set;}

    public int Experience {get; set;}

    public bool IsRequired
    {
        get
        {
            Role.Equals("Manager") && Experience == 121 ||
            Role.Equals("Developer") && Experience == 4
        }
    }
}

请注意:

Required if不是内置属性。您需要下载并导入第三方库:

MVC Foolproof Validation

对于星号,在自定义助手类中,

您只需检查IsRequired属性:

bool required = metadata.IsRequired;
if(required) 
    labelText += "<span class=\"red\">*</span>";