Parameter Binding TypeConverter Error Handling

193 views Asked by At

I am using Parameter binding to bind a string to a type and then I was hoping to do some basic validation on it. But I can't seem to get the error messages to be helpful.

Originally I had:

    [HttpPost]
    [Route("user/{id:guid}/name/{name}")]
    public async Task<IHttpActionResult> PostUserName(Guid id, [FromUri] Request Name)
    {
        ....
    }

public class Request
{
    [Required]
    [StringLength(17, MinimumLength = 17, ErrorMessage = ValidationConstants.LengthMessage)]
    [RegularExpression(ValidationConstants.AlphaNumericRegex, ErrorMessage = ValidationConstants.AlphaNumericMessage)]
    public string Name { get; set; }
}

And the error messaging looked great but then my request URI looked like this:

http://localhost:2010/v2/users/{id}/name/{Name}?name.Name=784598143uurjkndgkjhajkdhfkladshfkjahsdkfjl

Then I tried

    [HttpPost]
    [Route("user/{id:guid}/name/{name}")]
    public async Task<IHttpActionResult> PostUserName(Guid id, Request name)
    {
        .....
    }


    [TypeConverter(typeof(RequestConverter))]
    public class Request
    {
        [Required]
        [StringLength(50, MinimumLength = 1, ErrorMessage = ValidationConstants.LengthMessage)]
        [RegularExpression(ValidationConstants.AlphaNumericRegex, ErrorMessage = ValidationConstants.AlphaNumericMessage)]

        public string Name { get; set; } 

        public static bool TryParse(string s, out Request result)
        {
            result = new Request() { Name = s };
           if (result.Name != null)
           {
                return false;
            }

            return true;
        }
    }

    class RequestConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
            {
                return true;
            }
            return base.CanConvertFrom(context, sourceType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context,
            CultureInfo culture, object value)
        {
            if (value is string)
            {
                Request t;
                try
                {
                    if (Request.TryParse((string)value, out t))
                    {
                        return t;
                    }
                }
                catch (Exception e)
                {
                    throw e; 
                }
            }
            return base.ConvertFrom(context, culture, value);
        }
    }
}

For this the URI looks good:

http://localhost:2010/v2/users/{id}/name/784598143uurjkndgkjhajkdhfkladshfkjahsdkfjl

But the validation doesn't work and when I try throwing exceptions the error messages are generic.

The reason I chose to do it this way is I want the name to be a URI parameter, but I also want to do validation on it and have the error message be meaningful.

Is there a simpler way to do this or an I missing something simple?

0

There are 0 answers