Question

I'm becoming quite confused about how model binding, and specifically model validation occurs in Web API. The majority of my actions receive objects through POST requests, and my models have a variety of ValidationAttributes applied to them, such as RequiredAttribute, MinLengthAttribute, StringLengthAttribute etc.

One of my actions, however, is a GET request, and has a signature similar to this:

public SearchResultCollection Search([FromUri]SearchRequest request)

Originally, it looked like the below, but I then discovered you can create a single class that encapsulates the arguments that come in on the query string:

public SearchResultCollection Search(string searchPath, string searchValue, int limit, string sortBy)

Using the latter, I was unable to get any form of validation working on the arguments. As an example, applying the RequiredAttribute to the searchPath parameter seemingly did nothing. That prompted the change to the action signature, and the creation of the SearchRequest class, that looks like this:

public class SearchRequest
{
    public SearchRequest()
    {
        SortBy = SearchSortingKey.Id;
    }

    [Required(ErrorMessage="A search path must be specified.")]
    public string SearchPath{ get; set; }

    [Required(ErrorMessage="A search value must be specified.")]
    public string SearchValue{ get; set; }

    [Required(ErrorMessage="A limit be specified.")]
    public int Limit { get; set; }

    public SearchSortingKey SortBy { get; set; }
}

Using this method, it seems as though the RequiredAttributes are recognised (they cause model validation to fail), but the error message returned whilst performing model validation isn't the one that I specified in the RequiredAttributes above.

I don't have this problem when doing model validation with POST requests, and don't completely understand why it behaves differently when the model comes via the query string.

Can someone shed some light on this? I'd like to understand how to validate arguments passed in on the querystring - I assumed there would be some other way besides performing the validation in the action body.

I read the article here, but it doesn't really explain how or why model validation differs when the model comes in on the query string.

Was it helpful?

Solution

The issue you describe is (was) a bug in ASP.NET WebApi that was just recently resolved. You can find the details at http://aspnetwebstack.codeplex.com/workitem/1471.

For your string properties you should be able to use [Required] but add the parameter AllowEmptyStrings=false. I only required the work-around (as described by the bug reporting developer) for non-string properties.

And you may want to make your int property nullable (int?) if you're using JSON for deserialization; without making it int? Newtonsoft.Json converts and empty string for the property to 0.

/SearchRequest?SearchPath=[some string]&SearchValue=[some string]&SortBy=[some string]&Limit=

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top