5

I have implemented an OWIN self-hosted webapi and am trying to use data annotations and an ActionFilterAttribute to return formatted errors to the user. I have set custom error messages on the data annotation but when I try to retrieve the message from the ModelState it is always an empty string (shown in image below).

enter image description here

Model:

public class JobPointer
{
    [Required(ErrorMessage = "JobId Required")]
    public Guid JobId { get; set; }
}

Filter:

public class ModelValidationFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.ModelState.IsValid) return;
        string errors = actionContext.ModelState.SelectMany(state => state.Value.Errors).Aggregate("", (current, error) => current + (error.ErrorMessage + ". "));

        actionContext.Response = actionContext.Request.CreateErrorResponse(
            HttpStatusCode.BadRequest, errors);
    }

}

Endpoint:

[HttpPost]
public HttpResponseMessage DescribeJob(JobPointer jobId)
{

   Job job = _jobhelper.GetJob(jobId.JobId);
   return Request.CreateResponse(HttpStatusCode.OK, job);
}

Request Body:

{

}

Response:

Status Code: 400
{
  "Message": ". "
}

If I change error.Message in ModelValidationFilter to error.Exception.Message I get back the default validation error:

Status Code: 400
{
  "Message": "Required property 'JobId' not found in JSON. Path '', line 3, position 2.. "
}
3
  • can you add your API call and full response details? do you get a 400 bad request with empty response. the little snapshot shows a JSON exception for jobid.. try to make the field nullable (Guid?) and try again. in any case, please provide more details. controller action method, maybe a fiddler request/response. Commented Aug 28, 2015 at 9:03
  • I am sending a blank json block , I will add the code for the endpoint being called. I properly get 400 bad request and I can return the exception message properly that states "Required property 'JobId' not found..." but i would like to return my custom message. Commented Aug 28, 2015 at 13:35
  • 1
    Did you ever find the solution to this? Commented Nov 14, 2016 at 14:24

1 Answer 1

2

I know this is an old question, but I just had this problem and found the solution myself.

As you no doubt discovered, as Guid is a non-nullable type [Required] produces an unfriendly error message (I assume because the JSON parser picks it up before actually getting the model validation).

You can get around this by making the Guid nullable...

public class JobPointer
{
    [Required(ErrorMessage = "JobId Required")]
    public Guid? JobId { get; set; }
}

... however, this is not a viable option in all cases (as in my case), so I ended up writing my own validation attribute that would check the property against it's Empty declaration...

public class IsNotEmptyAttribute : ValidationAttribute
{

    public override bool IsValid(object value)
    {

        if (value == null) return false;

        var valueType = value.GetType();
        var emptyField = valueType.GetField("Empty");

        if (emptyField == null) return true;

        var emptyValue = emptyField.GetValue(null);

        return !value.Equals(emptyValue);

    }
}

You could then implement like...

public class JobPointer
{
    [IsNotEmpty(ErrorMessage = "JobId Required")]
    public Guid JobId { get; set; }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.