DefaultModelBinder not binding model (always null) even though ModelState contains all required values

1k views Asked by At

I am working with the sample ASP.NET MVC 3 application. I am working on a proof of concept for an API for a project I'm working on, by sending log in requests using HttpWebRequests. I am submitting data as JSON and am using the Content Type "application/json".

Here is the method I have:

[HttpPost]
[Api]
public bool ApiLogOn(LogOnModel model)
{
    if (ModelState.IsValid && model != null)
    {
        if (Membership.ValidateUser(model.UserName, model.Password))
        {
            FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
            return true;
        }
    }

    return false;
}

The problem is that even though ModelState contains all the keys and values that I expect to see (e.g. Dictionary contains { "UserName"="username", "Password"="password", "RememberMe"=true } which are the three properties of the LogOnModel class), the object model is null every time I call the method.

I do not have this problem when using "application/x-www-form-urlencoded". I have also tried with and without adding

ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());

to my Application_Start method.

Here is the code I am using to send requests to the method above:

var credentials = new LogOnModel() { UserName = "username", Password = "password", RememberMe = true };
var result = PostData<LogOnModel, bool>(@"url goes here", credentials);

protected R PostData<T, R>(string uri, T postData)
{
    var request = WebRequest.Create(uri) as HttpWebRequest;
    request.Headers.Add("X-Requested-With", X_REQUESTED_WITH_HEADER);
    request.Accept = "application/json";
    request.Method = "POST";
    request.CookieContainer = cookieJar;
    request.ContentType = "application/json";

    var serializerT = new DataContractJsonSerializer(typeof(T));
    var serializerR = new DataContractJsonSerializer(typeof(R));

    if (postData != null)
    {
        using (var stream = request.GetRequestStream())
        {
            serializerT.WriteObject(stream, postData);
        }
    }

    try
    {
        var response = request.GetResponse() as HttpWebResponse;

        if (response.StatusCode == HttpStatusCode.OK)
        {
            using (var stream = response.GetResponseStream())
            {
                var result = (R)serializerR.ReadObject(stream);
                return result;
            }
        }
        else
        {
            return default(R);
        }
    } catch { return default(R); }
 }
1

There are 1 answers

0
Dan Joseph On BEST ANSWER

It turns out that removing the [Api] Attribute solved my problem. If anyone is interested, it came from this url: http://mvcapi.codeplex.com/

The point was such that we could use methods that had both Views (for our web page) and JSON results (for our API calls). If anyone has any other ideas for this (aside from the obvious if-this-return-view-else-return-json) please feel free to comment below, I'd like to hear them.