How can I validate Guid datatype?
Asked Answered
P

6

6

Is there a way to validate GUID datatype?

I'm using validation attributes. http://msdn.microsoft.com/en-us/library/ee707335%28v=vs.91%29.aspx

Pinafore answered 30/11, 2011 at 23:43 Comment(0)
C
6

You can use a RegularExpressionAttribute. Here's a sample using the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:

[RegularExpression(Pattern = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}")]

You can also create a custom validation attribute, which is probably a cleaner solution.

Cabman answered 30/11, 2011 at 23:50 Comment(1)
It looks to me like this regex would accept 00000000-0000-0000-0000-000000000000, which I would be wary of, because it is what people would get if they said new Guid() by accident, instead of Guid.NewGuid()Grant
N
4

You could write your own subclass of CustomValidationAttribute that ensures the value is a guid by using the TryParse method of System.Guid (thanks Jon!).

Nonintervention answered 30/11, 2011 at 23:51 Comment(2)
Or TryParse rather than construct, so it will be control-flow rather than exception handling to catch the failure case.Gervase
Agreed. TryParse is the better way to do it.Nonintervention
P
1

I know this question is really old, but thought I'll chip in my answer in hope that it can help others in the future looking for the simplest solution using Validation Attribute.

I've found that the best solution is to implement the Validation Attribute and use Microsoft's TryParse method (instead of writing our own regex):

public class ValidateGuid : System.ComponentModel.DataAnnotations.ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        return System.Guid.TryParse(value.ToString(), out var guid) ? ValidationResult.Success : new ValidationResult("Invalid input string.");
    }
}

And then use it like this:

    [ValidateGuid]
    public string YourId { get; set; }

The additional good thing about this is that if the application is validating the request body of an API call and YourId is not a valid GUID, it will nicely response back with a 400 error - and the response body will have the error message that you specified ("Invalid input string."). No need to write custom error-handling logic :)

Pharisaism answered 22/3, 2021 at 12:47 Comment(4)
Nice! But I think it's kind of convention to add "Attribute" to attribute class names. I.e. "ValidateGuidAttribute". You can then still use it with [ValidateGuid]Putrescent
I looked into this a bit more, and Microsoft also uses a Regex internally for thisPutrescent
@Putrescent yes that's true, but Microsoft must have done rigorous testing with their Regexes, which significantly reduces the chances of problems compared to using our own regexes. Thanks for pointing it out though :)Pharisaism
This one does not show the name of the field/property having the error unfortunately. I made some changes (see my answer below) :)Pleistocene
A
0

This function might help you....

public static bool IsGUID(string expression)
{
    if (expression != null)
    {
        Regex guidRegEx = new Regex(@"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");

        return guidRegEx.IsMatch(expression);
    }
    return false;
}

You may remove the static or put the function in some Utility Class

Accident answered 1/12, 2011 at 4:26 Comment(1)
It looks to me like this regex would accept 00000000-0000-0000-0000-000000000000, which I would be wary of, because it is what people would get if they said new Guid() by accident, instead of Guid.NewGuid()Grant
G
0

This will use .Net's built-in Guid type for the validation, so you don't have to use a custom regular expression (which hasn't undergone Microsoft's rigorous testing):

public class RequiredGuidAttribute : RequiredAttribute
{
    public override bool IsValid(object value)
    {
        var guid = CastToGuidOrDefault(value);

        return !Equals(guid, default(Guid));
    }

    private static Guid CastToGuidOrDefault(object value)
    {
        try
        {
            return (Guid) value;
        }
        catch (Exception e)
        {
            if (e is InvalidCastException || e is NullReferenceException) return default(Guid);
            throw;
        }
    }
}

You then just use it like this:

    [RequiredGuid]
    public Guid SomeId { get; set; }

If any of the following are provided to this field, it will end up as a default(Guid), and will be caught by the Validator:

{someId:''}
{someId:'00000000-0000-0000-0000-000000000000'}
{someId:'XXX5B4C1-17DF-E511-9844-DC4A3E5F7697'}
{someMispelledId:'E735B4C1-17DF-E511-9844-DC4A3E5F7697'}
new Guid()
null //Possible when the Attribute is used on another type
SomeOtherType //Possible when the Attribute is used on another type
Grant answered 11/3, 2016 at 3:15 Comment(0)
P
0

Based on @ABVincita's answer I'm using this one:

   using System.ComponentModel.DataAnnotations;
    namespace MyProject.Common.Attributes
    {
        public class ValidGuidAttribute : ValidationAttribute
        {
            public ValidGuidAttribute() : base("The field {0} must be a valid GUID.")
            {
            }
            public override bool IsValid(object value)
            {
                return System.Guid.TryParse(value.ToString(), out var guid);
            }
        }
    }

To use it on a property:

[ValidGuid]
public string ApiId { get; set; }

The error message will also show the name of the field not having a valid GUID.

Pleistocene answered 21/2 at 11:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.