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.
Create target "JSON object Mapper" object class file according to the business requirements. Create a "Controllers\HomeController. cs" file with default Index method and GetData(...) method with string type input query parameters for Ajax call with following lines of code i.e.
To post JSON to a REST API endpoint, you must send an HTTP POST request to the REST API server and provide JSON data in the body of the POST message. You also need to specify the data type in the body of the POST message using the Content-Type: application/json request header.
Specify the POST data: As per the HTTP specification for a POST request, we pass data through the message body. Using requests, you'll pass the payload to the corresponding function's data parameter. Data can be anything including JSON, dictionary, a list of tuples, bytes, or a file-like object.
Very important caveat, even in MVC3, about the way MVC3 works.
If you pass an object like say:
{
Test: 'Hi'
}
And the receiving class is:
public class MyModel
{
public string Test { get; set; }
}
With a receiving Controller method like:
[HttpPost]
public JsonResult Submit(MyModel model)
{
. . .
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.
hmm....
I do it
$.post(target,
{
"ProblemId": id,
"Status": update
}, ProcessPostResult);
with
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") %>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With