Posting JSON to Controller

Posting JSON to Controller

I've got this in my controller:

    [HttpPost]     public void UpdateLanguagePreference(string languageTag)     {         if (string.IsNullOrEmpty(languageTag))         {             throw new ArgumentNullException("languageTag");         }          ...     } 

And have this jQuery code POSTing to the controller:

           jQuery.ajax({                 type: 'POST',                 url: '/Config/UpdateLanguagePreference',                 contentType: 'application/json; charset=utf-8',                 data: '{ "languageTag": "' + selectedLanguage + '" }'             }); 

When I try to the code, however, I get the error:

Server Error in '/' Application. Value cannot be null. Parameter name: languageTag 

What's the problem? Isn't this how to POST JSON to an MVC Controller? I can examine the POST using Fiddler and see that the request is correct. For some reason, UpdateLanguagePreference() is getting a null or empty string.

Is ADO.NET Entity Framework (with ASP.NET MVC v2) a viable option when writing custom and contantly updated websites?


How to disable VS compile warning “class or css class is not defined”
Very important caveat, even in MVC3, about the way MVC3 works..
patterns to use when building complex web UI
If you pass an object like say:.
Validation not firing even when my form is obviously invalid
​{     Test: 'Hi' } 
And the receiving class is:. mvc datannotation password validate
public class MyModel {     public string Test { get; set; } } 
With a receiving Controller method like:.
ASP.NET MVC - How controls retain their state
[HttpPost] public JsonResult Submit(MyModel model) {     . 

JavaScript url auto-resolution in Asp.Net MVC

How Testing relates to ASP.NET MVC/WEBFORMS Silverlight MVVM

It will work.

But if your Controller method has this very minor, seemingly harmless change:.
[HttpPost] public JsonResult Submit(MyModel test) {     . 



It will fail.

This is because the MVC framework consumes the JSON into a Dictionary as mentioned above, and sees that one of the parameters has the same name, case-insensitive, as one of its keys ("Test"/"test").

It then takes the string value "Hi", assigned to Test, and passes that to this argument "test" even though this is obviously not what the author intended.. What's most problematic about this is that the framework doesn't throw an error trying to assign a string to an arg of type MyModel, which would at least give you a clue about what went wrong.

It doesn't see this was the wrong type and fallback to its alternative behavior (that it would have pursued had these arg/properties not matched in name).

It simply fails silently and assigns null to your argument, leaving you with no clue as to what's going on.. I've run into this problem repeatedly and finally found the glitch that makes things seem to randomly stop working in MVC...

I hope this helps someone else.. Since any reasonable name for this Action argument is a potentially reasonable property name (model, data, etc) and since it's case-insensitive, the safest way to prevent it without writing your own model binder is to standardize on one, crazy, very-unlikely-to-ever-be-a-property-name argument name, like:.
[HttpPost] public JsonResult Submit(MyModel _$_$twinkleTwinkleLittleFuckIt) { 
But if you have the time, fix the ModelBinder/JsonValueProviderFactory so there's 0 risk instead of that one weird bug in a decade no one can ever get to the bottom of..


You are posting a string and not a JSONified object.. data: '{ "languageTag": "' + selectedLanguage + '" }'. should be . data: { "languageTag": selectedLanguage }. And make sure selectedLanguage is defined within the scope of your ajax call..


When you give jQuery's $.ajax() function a data variable in the form of a javascript object, it actually translates it to a series of key/value pairs and sends it to the server in that manner.

When you send the stringified json object, it's not in that form and the standard model binder in mvc/mvc2 won't cut it.. If you want to send post data in such a way, then you're very nearly there.

You need the JsonValueProviderFactory class found in MVC2 Futures/MVC3 Beta.

Take a look at the following links for more info:. ...

there's another link I used when implementing this myself that talked more about bringing the JsonValueProviderFactory class into your app, but I can't find it for the life of me..


hmm..... I do it.
 $.post(target,          {              "ProblemId": id,              "Status": update          }, ProcessPostResult); 
public class ProblemReportUpdate     {         public int ProblemId { get; set; }         public string Status { get; set; }     } 
and .
 [HttpPost]  public ActionResult UpdateProblemReport(ProblemReportUpdate update) 
the target is set by.
var target = '<%=Url.Action("UpdateProblemReport", "ProblemReport") %> 

52 out of 100 based on 27 user ratings 852 reviews