Either ErrorMessageString or ErrorMessageResourceName must be set, but not both error using CreditCardAttribute
This is my model:
namespace MvcApplication2.Models
{
public class CreditCard
{
[CreditCard(ErrorMessageResourceType = typeof(Messages), ErrorMessageResourceName = "CardNumberInvalid")]
public string CardNumber { get; set; }
}
}
This is my Messages.resx:
Name Value
CardNumberInvalid Check your card number is correct
And this is my view:
@model MvcApplication2.Models.CreditCard
@Html.TextBoxFor(m => m.CardNumber);
In MVC version 3 this works without error. In MVC 4 when I go to this page I get an excpetion saying "Either ErrorMessageString or ErrorMessageResourceName must be set, but not both". This is only happening with the CreditCardAttribute. Other validation attributes such as RequiredAttribute work fine. I have only set the ErrorMessageResourceName. I have not set the ErrorMessageString, so do not understand what I have done wrong. Can anyone help please?
It's a known issue in .Net 4.5. Adding "ErrorMessage = null" named parameter should solve this.
Reference:
Reference link is broken now.
http://connect.microsoft.com/VisualStudio/feedback/details/757298/emailaddress-attribute-is-unable-to-load-error-message-from-resource-mvc
[CreditCard(ErrorMessageResourceType = typeof(Messages), ErrorMessageResourceName = "CardNumberInvalid", ErrorMessage = null)]
Adding the ErrorMessage = null
will fix your problem.
I had this problem because I had implemented a RequiredAttributeAdapter
, which was setting the ErrorMessageResourceName
property automatically.
You can fix it by checking to see if the ErrorMessage property has been set before setting the ErrorMessageResourceName
:
/// <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";
}
}
Since anyone who is using custom validation attributes and also wants to load error messages from resources for localization purposes, would face this problem i share my workaround here.
assume that you have a custom validation attribute like this one
[FileTypeMustBe("jpg")]
public HttpPostedFileBase MyFile {get; set;}
in your custom validation attribute add this code
public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture,
ErrorMessageString, name, ValidFileType);
}
ValidFileType is name of a property which takes the input argument of custom validation attribute (jpg here),well now we can decorate our model property the way we like it to be
[FileTypeMustBe("jpg", ErrorMessageResourceType = typeof(Resources.Resources), ErrorMessageResourceName = "WrongFileTypeError")]
public HttpPostedFileBase MyFile {get; set;}
as you see there's no need to add ErrorMessage=null
anymore cause we took care of it in custom validation class. just do not forget if you had initialized any error message string in your custom validation , you have to remove it now and use FormatErrorMessage
instead.