ASP.NET MVC C#DataTypeAttribute on parameter

问题描述 投票:0回答:1

我已尝试在发布到控制器的参数上使用EmailAddressAttribute,但它与在模型中使用的效果不同。

这是我的代码:

    public void AddEmail(int id, [EmailAddress]string emailAddress)
    {
        if (!ModelState.IsValid)
            throw new Exception();
    }

emailAddress参数在ModelState内,但它始终有效。但是,如果我在下面的模型中使用它,那么它的工作完全正常。

    public class TestModel
    {
        public int Id { get; set; }
        [EmailAddress]
        public string EmailAddress { get; set; }
    }

    public void AddEmail(TestModel model)
    {
        if (!ModelState.IsValid)
            throw new Exception();
    }

EmailAddressAttribute类有AttributeTargets.Parameter所以我认为它会工作相同。

任何人都可以确认这是否就是这样吗?或者有没有办法让它像模型一样工作?

编辑:我正在使用.NET Framework 4.6.2。

谢谢

c# asp.net-mvc attributes modelstate
1个回答
0
投票

我不知道你是否可以在函数中使用DataTypeAttributes作为参数。但作为一种简单的方法来检查它是否是有效的电子邮件表示法,您可以使用此代码:

try {
    var addr = new System.Net.Mail.MailAddress(email);
    return addr.Address == email;
}
catch {
    return false;
}

编辑1:

正如Mark Vincze here在他的博客中所提到的,当你想在你的动作参数中拥有属性时,你可以创建一个像这样的新ActionFilterAttribute

public class ValidateActionParametersAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var descriptor = context.ActionDescriptor as ControllerActionDescriptor;

        if (descriptor != null)
        {
            var parameters = descriptor.MethodInfo.GetParameters();

            foreach (var parameter in parameters)
            {
                var argument = context.ActionArguments[parameter.Name];

                EvaluateValidationAttributes(parameter, argument, context.ModelState);
            }
        }

        base.OnActionExecuting(context);
    }

    private void EvaluateValidationAttributes(ParameterInfo parameter, object argument, ModelStateDictionary modelState)
    {
        var validationAttributes = parameter.CustomAttributes;

        foreach (var attributeData in validationAttributes)
        {
            var attributeInstance = CustomAttributeExtensions.GetCustomAttribute(parameter, attributeData.AttributeType);

            var validationAttribute = attributeInstance as ValidationAttribute;

            if (validationAttribute != null)
            {
                var isValid = validationAttribute.IsValid(argument);
                if (!isValid)
                {
                    modelState.AddModelError(parameter.Name, validationAttribute.FormatErrorMessage(parameter.Name));
                }
            }
        }
    }
}

但这也适用于Actions。因为创建ModelState-Class是为了更容易检查传入的绑定是否有效,而不仅仅是验证随机对象。 Here更多的是关于这一点。

因此,在你的情况下,当AddEmail是一种“正常”方法而不是Action时,你不应该使用它。在这种情况下,请使用其他验证方法,例如我的第一个答案。

如果您想了解更多有关验证的信息,请查看Brad Wilson的this博客文章。

© www.soinside.com 2019 - 2024. All rights reserved.