0

[Edit: the original code snippets were not correct.]

[This post is intented to help answer the specific question I had which I found a great answer to. I am linking to my example post that I followed and then the post that gave me the answer. Then I am posting the code that I used successfully to produce the results I achieved.]

I implemented a simple technique for Validation in my input to an ApiController. The following code was functional, but as you can see it only provided a generic error message.

The answer I found to guide me to this technique is found here: https://stackoverflow.com/a/19322688/7637275

The following is my code that I started with -

using System.Web.Http;
using System.Web.Routing;
using System.Web.Http.Controllers;
using System.Web;
using System.Web.Http.Filters;

namespace TestValidation
{
    internal class ValidateModelStateFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (!actionContext.ModelState.IsValid)
            {
                throw new HttpException(422, "Validation failed on input");
            }
        }
    }
}

The following snippet shows the validation error I needed to see, instead of the generic message noted above.

[Required(ErrorMessage = @"Parameter ""ID"" is required.")]
[MaxLength(18, ErrorMessage = @"Exceeded max length (18 characters) for parameter ""ID""")]
public string ID { get; set; }

At this point, within my override, I need to dig into the HttpActionContent object "actionContext" to find the customized error messages.

1 Answers1

0

[Edit: the original code snippets were not correct.]

I found a great posted answer that helped me resolve my question! The following link takes you to that answer: https://stackoverflow.com/a/33009722/7637275

Here is the resulting code that I used to provide the custom validation messages from my web service. I made three small adjustments. I chose to implement a Try/Catch block that simply provides the generic error message if the code fails. I used a List instead of a var (coding style). I also used a semi-colon instead of a newline to join the errors (this fits my requirement).

A huge thank you to both posters in stackoverflow that helped me get to the bottom of this!

using System.Web.Http;
using System.Web.Routing;
using System.Web.Http.Controllers;
using System.Web;
using System.Web.Http.Filters;
using System.Linq;
using System.Collections.Generic;


namespace TestValidation
{
    internal class ValidateModelStateFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (!actionContext.ModelState.IsValid)
            {
                string errorMessage = string.Empty;

                List<string> errors = new List<string>();

                try
                {
                    errors = actionContext.ModelState.Values.SelectMany(val => val.Errors.Select(err => err.ErrorMessage)).ToList();

                    errorMessage = string.Join(";", errors);
                }
                catch                   {
                    errorMessage = "Validation failed on input";
                }

                throw new HttpException(422, errorMessage);
            }
        }
    }
}