Either ErrorMessageString or ErrorMessageResourceName must be set, but not both error using CreditCardAttribute

asp.net Mvcasp.net Mvc-4

asp.net Mvc Problem Overview


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?

asp.net Mvc Solutions


Solution 1 - asp.net Mvc

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</s>

Solution 2 - asp.net Mvc

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

Adding the ErrorMessage = null will fix your problem.

Solution 3 - asp.net Mvc

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";
    }
}

Solution 4 - asp.net Mvc

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.

Solution 5 - asp.net Mvc

I had a simmilar issue with a custom ValidationAttribute.

In the IsValid method I was setting the ErrorMessage. The fix was to remove the assignation to the 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;
}

I was writting Unit test and they were pasisng only if i was running/debugging one by one. But when I click "Run All", only the first one was passing? They are not Linked in any ways...

So yeah, just remove the remove the assignation to the ErrorMessage propety

I hope it will help someone!

Solution 6 - asp.net Mvc

In my case, I was using ErrorMessage as "" in .Net Core 3.1 API.

[Required]
[RegularExpression("^[1-9]\\d*$", ErrorMessage ="")]
public int fieldName { get; set; }

I change to ErrorMessage ="Invalid Value Or some other message" and the issue is solved.

Solution 7 - asp.net Mvc

Replacing

[Required(ErrorMessage = "")]

with

[Required()]

worked for me, there is no meaning of keeping ErrorMessage with a blank string either

Solution 8 - asp.net Mvc

I ran into this when using a custom 'ValidationAttribute' that returned a ValidationResult instead of a bool. When I returned an unassigned string with the ValidationResult it would throw the error

Either ErrorMessageString or ErrorMessageResourceName must be set, but not both

When I returned ValidationResult(null) the field would never validate, it was always invalid. Looks like .NET looks for a ValidationResult to determine if the field is valid and not if it contains an error string. In order to get it to validate and get rid of the error I needed to return a null result.

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;
}

Solution 9 - asp.net Mvc

I had this same problem on a property that I was localizing. I had defined the ErrorMessageResourceType and then the ErrorMessageResourceName but by mistake put the ErrorMessage atrtribute on as well which threw the exception

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

So in my case by just removing ErrorMessage I fixed the problem.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionisxpjmView Question on Stackoverflow
Solution 1 - asp.net MvcDipen BhikadyaView Answer on Stackoverflow
Solution 2 - asp.net MvcAhm3d SaidView Answer on Stackoverflow
Solution 3 - asp.net MvcIan NewsonView Answer on Stackoverflow
Solution 4 - asp.net MvcAmin KView Answer on Stackoverflow
Solution 5 - asp.net MvcIannick View Answer on Stackoverflow
Solution 6 - asp.net Mvcvivek nunaView Answer on Stackoverflow
Solution 7 - asp.net MvcmijavedView Answer on Stackoverflow
Solution 8 - asp.net MvcAndy BrahamView Answer on Stackoverflow
Solution 9 - asp.net MvcFleaView Answer on Stackoverflow