必须设置ErrorMessageString或ErrorMessageResourceName,但不能使用CreditCardAttribute设置错误

时间:2012-09-18 10:12:22

标签: asp.net-mvc asp.net-mvc-4

这是我的模特:

namespace MvcApplication2.Models
{
    public class CreditCard
    {
        [CreditCard(ErrorMessageResourceType = typeof(Messages), ErrorMessageResourceName = "CardNumberInvalid")]
        public string CardNumber { get; set; }
    }
}

这是我的Messages.resx:

名称值

CardNumberInvalid检查您的卡号是否正确

这是我的观点:

@model MvcApplication2.Models.CreditCard
@Html.TextBoxFor(m => m.CardNumber);

在MVC版本3中,这可以正常工作。在MVC 4中,当我转到此页面时,我得到一个表示“必须设置ErrorMessageString或ErrorMessageResourceName,但不能同时设置两者”的删除操作。这只发生在CreditCardAttribute上。其他验证属性(如RequiredAttribute)工作正常。我只设置了ErrorMessageResourceName。我没有设置ErrorMessageString,所以不明白我做错了什么。有人可以帮忙吗?

9 个答案:

答案 0 :(得分:151)

这是.Net 4.5中的一个已知问题。添加“ErrorMessage = null”命名参数应解决此问题。

参考: 参考链接现已破裂。 http://connect.microsoft.com/VisualStudio/feedback/details/757298/emailaddress-attribute-is-unable-to-load-error-message-from-resource-mvc

答案 1 :(得分:13)

[CreditCard(ErrorMessageResourceType = typeof(Messages), ErrorMessageResourceName = "CardNumberInvalid", ErrorMessage = null)]

添加ErrorMessage = null将解决您的问题。

答案 2 :(得分:10)

我遇到了这个问题,因为我实施了RequiredAttributeAdapter,它自动设置ErrorMessageResourceName属性。

您可以通过在设置ErrorMessageResourceName之前检查是否已设置ErrorMessage属性来修复它:

/// <summary>
/// Creates a new instance of the RequiredAttributeAdapter, used for switching the default required message
/// format
/// </summary>
public CustomMessageRequiredAttributeAdapter(
    ModelMetadata metadata,
    ControllerContext context,
    RequiredAttribute attribute
)
    : base(metadata, context, attribute)
{
    if (string.IsNullOrEmpty(attribute.ErrorMessage))
    {
        attribute.ErrorMessageResourceType = typeof (ValidationMessages);
        attribute.ErrorMessageResourceName = "PropertyValueRequired";
    }
}

答案 3 :(得分:0)

由于任何使用自定义验证属性并且还希望从资源加载错误消息以进行本地化的人都会遇到此问题,因此我在此处分享我的解决方法。
假设您有一个像这样的自定义验证属性

[FileTypeMustBe("jpg")]
public HttpPostedFileBase MyFile {get; set;}

在自定义验证属性中添加此代码

public override string FormatErrorMessage(string name)
    {
        return String.Format(CultureInfo.CurrentCulture,
          ErrorMessageString, name, ValidFileType);
    }

ValidFileType是一个属性的名称,它接受自定义验证属性的输入参数(这里是jpg),现在我们可以按照我们喜欢的方式装饰我们的模型属性

[FileTypeMustBe("jpg", ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "WrongFileTypeError")]
public HttpPostedFileBase MyFile {get; set;}

如您所见,不再需要添加ErrorMessage=null因为我们在自定义验证类中处理它。只是不要忘记如果您在自定义验证中初始化了任何错误消息字符串,则必须立即将其删除并改为使用FormatErrorMessage

答案 4 :(得分:0)

我有一个自定义ValidationAttribute的问题。

在IsValid方法中,我设置了ErrorMessage。解决方法是删除对ErrorMessage propety的赋值...

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    //code before ...
    this.ErrorMessage = this.FormatErrorMessage(validationContext.DisplayName); //NOT GOOD...
    ValidationResult validationResult = new ValidationResult(this.ErrorMessage, //And using the ErrorMessage Here...
        new[] { validationContext.MemberName });
    return validationResult;
}

我正在编写单元测试,只有当我一个接一个地运行/调试时才会进行调试。但是当我点击“全部运行”时,只有第一个通过?他们没有以任何方式联系......

所以是的,只需删除删除ErrorMessage propety的分配

我希望它会帮助别人!

答案 5 :(得分:0)

就我而言,我在.Net Core 3.1 API中将includeResourceData用作ErrorMessage

""

我更改为[Required] [RegularExpression("^[1-9]\\d*$", ErrorMessage ="")] public int fieldName { get; set; } ,问题就解决了。

答案 6 :(得分:0)

替换

tt = 1605067706567342
n=500000
exact_time = []
for i in range(n):
    tt = tt + 99999
    # print(t)
    exact_time.append(tt)

type = [0,0,0,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,0,1,1,1,1]*10000

data = pd.DataFrame({'exact_time':exact_time,'type':type}, columns=['exact_time', 'type'])
print(data)
s2_data = data[data['type'] == 2]
s2_time_list = s2_data['exact_time'].tolist()
len(s2_time_list)

####Your method 1 - # 500,000 rows; 20,000 type 2 --- **46.63247585296631 seconds**
starttime = time.time()
new_data = pd.DataFrame()
for t in s2_time_list:
    # print(t)
    # print(data.loc[(data['exact_time'] >= t-1e6) & (data['exact_time'] <= t)])
    new_data = new_data.append(data.loc[(data['exact_time'] >= t-1e6) & (data['exact_time'] <= t)])
print(time.time()-starttime)
 
#### Reworked to create list of dfs then concatenate
### # 500,000 rows; 20,000 type 2 --- **25.308656930923462 seconds**
starttime = time.time()
new_data_list = []
for t in s2_time_list:
    # print(t)
    # print(data.loc[(data['exact_time'] >= t-1e6) & (data['exact_time'] <= t)])
    new_data_list.append(data.loc[(data['exact_time'] >= t-1e6) & (data['exact_time'] <= t)])
new_df = pd.concat(new_data_list, axis=0)
print(time.time()-starttime)
 

使用

[Required(ErrorMessage = "")]

为我工作,也没有将 ErrorMessage 保留为空字符串的意思

答案 7 :(得分:0)

我在使用返回 ValidationResult 而不是 bool 的自定义“ValidationAttribute”时遇到了这个问题。当我返回一个带有 ValidationResult 的未分配字符串时,它会抛出错误

Either ErrorMessageString or ErrorMessageResourceName must be set, but not both

当我返回 ValidationResult(null) 时,该字段永远不会验证,它总是无效的。看起来 .NET 会查找 ValidationResult 来确定该字段是否有效,而不是它是否包含错误字符串。为了让它验证并消除错误,我需要返回一个 null 结果。

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    string errMsg = null;

    // Do validation and assign the error message

    return (!string.IsNullOrEmpty(errMsg)) ? new ValidationResult(errMsg) : null;
}

答案 8 :(得分:-1)

我在本地化的属性上遇到了同样的问题。我已经定义了ErrorMessageResourceType,然后定义了ErrorMessageResourceName但是错误地将ErrorMessage atrtribute也放在了引发异常的地方

[NotEqualTo("User_Name", ErrorMessageResourceType = typeof(LROResources.Global), ErrorMessageResourceName = "UserPasswordCannotBeUsername", ErrorMessage = "The password cannot be the same as your Username.")]

所以在我的情况下,只需删除ErrorMessage我就解决了问题。