ASP.NET MVC 2自定义ModelValidator问题 [英] ASP.NET MVC 2 Problem with custom ModelValidator

查看:100
本文介绍了ASP.NET MVC 2自定义ModelValidator问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想验证,要么在我看来2文本字段具有提供的值。我提出这个型号验证:

 公共类RequireEitherValidator:ModelValidator
{
    私人只读字符串选择compareProperty;
    私人只读字符串的errorMessage;

    公共RequireEitherValidator(ModelMetadata元数据,
    ControllerContext背景下,串选择compareProperty,字符串的errorMessage)
        :基地(元数据,上下文)
    {
        this.compareProperty =选择compareProperty;
        this.errorMessage =的errorMessage;
    }

    公共覆盖的IEnumerable< ModelValidationResult>验证(对象容器)
    {
        如果(Metadata.Model == NULL)
            产生中断;
        VAR的PropertyInfo = container.GetType()的getProperty(选择compareProperty)。
        如果(的PropertyInfo == NULL)
            抛出新的InvalidOperationException异常(未知的属性:+选择compareProperty);

        字符串valueToCompare = propertyInfo.GetValue(集装箱,空)的ToString();

        如果(string.IsNullOrEmpty(Metadata.Model.ToString())及&安培; string.IsNullOrEmpty(valueToCompare))
            收益回报新ModelValidationResult
            {
                消息=的errorMessage
            };
    }
}
 

此验证逻辑从来没有被击中,我想这是因为没有价值被提供给文本框。

在的情况下你需要它,这里的供应商和属性我的属性使用创建沿:

 公共类MyValidatorProvider:AssociatedValidatorProvider
{
    保护覆盖的IEnumerable< ModelValidator> GetValidators(
        ModelMetadata元,ControllerContext的背景下,
        IEnumerable的<属性>属性)
    {
        的foreach(VAR ATTRIB在attributes.OfType< RequireEitherAttribute>())
            产量返回新RequireEitherValidator(元数据的背景下,
            attrib.CompareProperty,attrib.ErrorMessage);
    }
}

公共类RequireEitherAttribute:属性
{
    公共只读字符串选择compareProperty;
    公共字符串的ErrorMessage {获得;组; }

    公共RequireEitherAttribute(字符串选择compareProperty)
    {
        选择compareProperty =选择compareProperty;
    }
}

公共类StudentLogin
{
    [显示名称(姓氏)
    [必需的(的ErrorMessage =您必须提供您的姓氏。)
    公共字符串名字{获得;组; }

    [DisplayName的(学号)]
    [RegularEx pression(@^ \ D {1,8} $的ErrorMessage =无效学生证)]
    [RequireEither(SSN的ErrorMessage =您必须提供学生证或社会安全号码。)
    公众诠释? StudentId {获得;组; }

    [DisplayName的(社会安全号)]
    [RegularEx pression(@^ \ D {9} | \ d {3}  -  \ d {2}  -  \ d {4} $的ErrorMessage =无效的社会安全号)]
    公共字符串SSN {获得;组; }
}
 

我的看法:

 <%Html.BeginForm(); %>
    &其中p为H.;
        请提供以下信息登录:LT; / P>
    <醇类=标准>
        <李>
            &其中p为H.;
                <%= Html.LabelFor(X => x.LastName)%>< BR />
                &其中;%= Html.TextBoxFor(X => x.LastName)%>
                &其中;%= Html.ValidationMessageFor(X => x.LastName)%>&所述; / P>
        < /李>
        <李>
            &其中p为H.;
                <%= Html.LabelFor(X => x.StudentId)%>< BR />
                &其中;%= Html.TextBoxFor(X => x.StudentId)%>
                &其中;%= Html.ValidationMessageFor(X => x.StudentId)%>&所述; / P>
            < P类=保证金左:4EM;>
                 - 或 - < / P>
            &其中p为H.;
                <%= Html.LabelFor(X => x.SSN)%>< BR />
                &其中;%= Html.TextBoxFor(X => x.SSN)%>
                &其中;%= Html.ValidationMessageFor(X => x.SSN)%>
            &所述; / P>
        < /李>
    < / OL>
    <%= Html.SubmitButton(提交,登录)%>
    &所述;%Html.EndForm(); %>
 

解决方案

接近这不仅仅是创建一个ValidationAttribute,并在类级别应用的一种方式。

  [RequireEither(StudentId,SSN)
公共类StudentLogin
 

,错误信息将自动显示在验证摘要。该属性会是这个样子(我已经彻底被处理一切为字符串只是为了简洁起见简化内部isValid()的验证逻辑:

 公共类RequireEither:ValidationAttribute
{
    私人字符串firstProperty;
    私人字符串secondProperty;

    公共RequireEither(字符串firstProperty,串secondProperty)
    {
        this.firstProperty = firstProperty;
        this.secondProperty = secondProperty;
    }

    公众覆盖布尔的IsValid(对象的值)
    {
        VAR firstValue = value.GetType()的getProperty(this.firstProperty).GetValue(值null)的字符串。
        VAR secondValue = value.GetType()的getProperty(this.secondProperty).GetValue(值null)的字符串。

        如果(!string.IsNullOrWhiteSpace(firstValue))
        {
            返回true;
        }

        如果(!string.IsNullOrWhiteSpace(secondValue))
        {
            返回true;
        }
        //没有供给,所以它不是有效的
        返回false;
    }
}
 

请注意,在这种情况下,传递给的IsValid()对象是类本身而不是属性的实例

I am trying to validate that either of 2 textbox fields in my view have a value supplied. I made this Model Validator:

public class RequireEitherValidator : ModelValidator
{
    private readonly string compareProperty;
    private readonly string errorMessage;

    public RequireEitherValidator(ModelMetadata metadata,
    ControllerContext context, string compareProperty, string errorMessage)
        : base(metadata, context)
    {
        this.compareProperty = compareProperty;
        this.errorMessage = errorMessage;
    }

    public override IEnumerable<ModelValidationResult> Validate(object container)
    {
        if (Metadata.Model == null)
            yield break;
        var propertyInfo = container.GetType().GetProperty(compareProperty);
        if (propertyInfo == null)
            throw new InvalidOperationException("Unknown property:" + compareProperty);

        string valueToCompare = propertyInfo.GetValue(container, null).ToString();

        if (string.IsNullOrEmpty(Metadata.Model.ToString()) && string.IsNullOrEmpty(valueToCompare))
            yield return new ModelValidationResult
            {
                Message = errorMessage
            };
    }
}

This validation logic never gets hit and I think it's because no value gets supplied to the textboxes.

In case you need it, here's the provider and attribute I created along with the attribute usage:

public class MyValidatorProvider : AssociatedValidatorProvider
{
    protected override IEnumerable<ModelValidator> GetValidators(
        ModelMetadata metadata, ControllerContext context,
        IEnumerable<Attribute> attributes)
    {
        foreach (var attrib in attributes.OfType<RequireEitherAttribute>())
            yield return new RequireEitherValidator(metadata, context,
            attrib.CompareProperty, attrib.ErrorMessage);
    }
}

public class RequireEitherAttribute : Attribute
{
    public readonly string CompareProperty;
    public string ErrorMessage { get; set; }

    public RequireEitherAttribute(string compareProperty)
    {
        CompareProperty = compareProperty;
    }
}

public class StudentLogin
{
    [DisplayName("Last Name")]
    [Required(ErrorMessage = "You must supply your last name.")]        
    public string LastName { get; set; }

    [DisplayName("Student ID")]
    [RegularExpression(@"^\d{1,8}$", ErrorMessage = "Invalid Student ID")]
    [RequireEither("SSN", ErrorMessage = "You must supply your student id or social security number.")]        
    public int? StudentId { get; set; }

    [DisplayName("Social Security Number")]
    [RegularExpression(@"^\d{9}|\d{3}-\d{2}-\d{4}$", ErrorMessage = "Invalid Social Security Number")]
    public string SSN { get; set; }
}

My view:

 <%Html.BeginForm(); %>
    <p>
        Please supply the following information to login:</p>
    <ol class="standard">
        <li>
            <p>
                <%=Html.LabelFor(x => x.LastName) %><br />
                <%=Html.TextBoxFor(x => x.LastName)%>
                <%=Html.ValidationMessageFor(x => x.LastName) %></p>
        </li>
        <li>
            <p>
                <%=Html.LabelFor(x => x.StudentId) %><br />
                <%=Html.TextBoxFor(x => x.StudentId) %>
                <%=Html.ValidationMessageFor(x => x.StudentId) %></p>
            <p style="margin-left: 4em;">
                - OR -</p>
            <p>
                <%=Html.LabelFor(x => x.SSN)%><br />
                <%=Html.TextBoxFor(x => x.SSN) %>
                <%=Html.ValidationMessageFor(x => x.SSN) %>
            </p>
        </li>
    </ol>
    <%=Html.SubmitButton("submit", "Login") %>
    <%Html.EndForm(); %>

解决方案

One way to approach this is not just create a ValidationAttribute and apply this at the class level.

[RequireEither("StudentId", "SSN")]
public class StudentLogin

The error message will automatically show up in the Validation Summary. The attribute would look something like this (I've drastically simplified the validation logic inside IsValid() by treating everything as strings just for brevity:

public class RequireEither : ValidationAttribute
{
    private string firstProperty;
    private string secondProperty;

    public RequireEither(string firstProperty, string secondProperty)
    {
        this.firstProperty = firstProperty;
        this.secondProperty = secondProperty;
    }

    public override bool IsValid(object value)
    {
        var firstValue = value.GetType().GetProperty(this.firstProperty).GetValue(value, null) as string;
        var secondValue = value.GetType().GetProperty(this.secondProperty).GetValue(value, null) as string;

        if (!string.IsNullOrWhiteSpace(firstValue))
        {
            return true;
        }

        if (!string.IsNullOrWhiteSpace(secondValue))
        {
            return true;
        }
        // neither was supplied so it's not valid
        return false;
    }
}

Note that in this case the object passed to IsValid() is the instance of the class itself rather than the property.

这篇关于ASP.NET MVC 2自定义ModelValidator问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆