1

I'm trying use data annotations to validate a number in .Net Core. If user check the Type checkbox number must be between 0.5 and 20 else between 0.5 and 100. Is there a way to use range data annotations?

like:

if (type)
 [Range(0.5, 20, ErrorMessage = "<20")]
else
 [Range(0.5, 100, ErrorMessage = "<100")]

or is there any way to do this?

Micky
  • 13
  • 5
  • 1
    is this what you are looking for ? https://stackoverflow.com/questions/23780943/how-to-create-custom-validation-attribute – Hoshani Oct 17 '21 at 12:47

3 Answers3

0

Do this validation using just if.

if (value < 0.5)
  throw new ArgumentOutOfRangeException();

if (type)
{
  if (value > 20)
    throw new ArgumentOutOfRangeException();
}
else 
{
  if (value > 100)
    throw new ArgumentOutOfRangeException();
}

You can't use Attribute as a statement. It's a part of a declaration. Use attributes to add some metadata to (class/field/method/argument/etc) declaration and read this data using reflection.

Data annotations can be used for validation or static analysis.


Read about Attributes in C# and Data annotations.

Wootiae
  • 728
  • 1
  • 7
  • 17
0

Technically I prefer to perform this kind of conditional validation on Frontend side. Server side validation is meant usually only for security reasons, as a last resort or for a basic validation: Don't let users inject Potatoes instead of Integers. So if you verify the maximum range boundaries that would be enough if the semantical validation is not critical from a security perspective.

If You insist or think that security can be broken and want to validate all the cases on Server side you can create a custom validation attribute by extending the .NET ValidationAttribute class:

https://learn.microsoft.com/de-de/dotnet/api/system.componentmodel.dataannotations.validationattribute?view=net-5.0

An example about how to use it here: ASP.NET MVC: Custom Validation by DataAnnotation

If You're writing an API in Core .NET yep, as stated by Wootiae You could throw an Exception and let Core .NET return an HTTP code from the range 400 which indicates a "Bad format". This should be done in the API method BODY. Something like this:

if (condition)
    return HttpBadRequest("Bad Request. Out of Range.");

Anyway, frontend code should still enforce this.

Edited

As suggested by pinkfloydx33

Claudio Ferraro
  • 4,551
  • 6
  • 43
  • 78
  • You should always validate your data on the serverside. Front end validation can be bypassed with some knowledge of browser Dev tools and not all requests get made through a browser (direct web api access). I'd argue you have it backwards – pinkfloydx33 Oct 17 '21 at 13:11
  • Aha. How do You bypass an IntRange ? You confuse semantical with basic validation – Claudio Ferraro Oct 17 '21 at 13:14
  • In this case you don't. But your answer reads as if it's arguing that any server side validation is pointless so long as you get it all right on the front end – pinkfloydx33 Oct 17 '21 at 13:17
  • I edited my answer but the question was not making this distiction, so I either. – Claudio Ferraro Oct 17 '21 at 13:41
0

You can implement your own custom validation attribute for this case.

Check out https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-5.0#custom-attributes.

You will have to take the bool flag (checkbox on or off) along with the range values as 'inputs' for that custom class.

Should be something like that:

public class NumberRangeByConditionAttribute : ValidationAttribute
{
    float _minRange, _maxRange;

    public NumberRangeByConditionAttribute (bool isChecked, float minWhenChecked, float maxWhenChecked, float minWhenUnchecked, float maxWhenUnchecked)
    {
        if (isChecked) 
        {
            _minRange = minWhenChecked;
            _maxRange = maxWhenChecked;
        }
        else 
        {
            _minRange = minWhenUnchecked;
            _maxRange = maxWhenUnchecked;
        }
    }

    public string GetErrorMessage() =>
        $"Number should be between {_minRange} and {_maxRange}.";

    protected override ValidationResult IsValid(object value,
        ValidationContext validationContext)
    {
        var number = (float)validationContext.ObjectInstance;

        if (number > _maxRange || number < _minRange)
        {
            return new ValidationResult(GetErrorMessage());
        }

        return ValidationResult.Success;
    }
}
Yom B
  • 228
  • 1
  • 10