简体   繁体   中英

ASP.NET mvc 4 controller parameter always null when sending json to controller, why?

There are some similar posts already here, and tried every solution suggested, and still does not work... I can not get value inside controller, it is always null. Below is the code. Am I missing something?

Client side javascript

   function getChart() {
       JSONString3 = { HAxis : [{ Name : "monday" }] };
       jQuery.ajaxSettings.traditional = true;
        $.ajax({
            url: "@Url.Action("getChart","SBM")",
            type: 'POST',
            contentType: 'json',
            dataType: 'html',
            data: JSONString3,
            success: function (data) {
                var imagestring = btoa(data);
                $('#ChartImage').attr('src', "data:image/png;base64," + imagestring + "?" + new       Date().getTime());
            }
        })
        jQuery.ajaxSettings.traditional = false;
    }

MVC Controller

    [Authorize]
    [HttpPost]
    public ActionResult getChart(YAxis HAxis)
    {
        YAxis XAxisvalue = HAxis;
        Charts chart = new Charts();
        MemoryStream ms = new MemoryStream();
        chart.Chart.SaveImage(ms);
        string image = Convert.ToBase64String(ms.GetBuffer());
        return File(ms.GetBuffer(), "image/png", "Chart.png");
    }

Model

public class YAxis
{
    public string Name { get; set; }
}

Thank you guys for the directions and solutions. The solution is a combination of all of your suggestions, so I decided to round it up in one post.

Solution to the problem is as follows:

  1. contentType should be application/json (as Ant P suggested above)
  2. json data should be in form of JSONString3 = {"Name" : "monday" } (as Ant P suggested above)
  3. before sending to controller, json should be stringifyed as follows: JSONString3 = JSON.stringify(JSONString3) (as Quan suggested)

Client side javascript

function getChart() {
               JSONString3 = { "Name" : "monday" };
               jQuery.ajaxSettings.traditional = true;
                $.ajax({
                    url: "@Url.Action("getChart","SBM")",
                    type: 'POST',
                    contentType: 'application/json',
                    dataType: 'html',
                    data: JSON.stringify(JSONString3),
                    success: function (data) {
                        var imagestring = btoa(data);
                        $('#ChartImage').attr('src', "data:image/png;base64," + imagestring + "?" + new       Date().getTime());
                    }
                })
                jQuery.ajaxSettings.traditional = false;
    }

MVC Controller

[Authorize]
[HttpPost]
public ActionResult getChart(YAxis HAxis)
{
    YAxis XAxisvalue = HAxis;
    Charts chart = new Charts();
    MemoryStream ms = new MemoryStream();
    chart.Chart.SaveImage(ms);
    string image = Convert.ToBase64String(ms.GetBuffer());
    return File(ms.GetBuffer(), "image/png", "Chart.png");
}

Model

public class YAxis
{
    public string Name { get; set; }
}

Instead of this:

JSONString3 = { "Name" : "monday" };

we can do this:

var JSONString3 = {};
JSONString.Name = "monday";

But we still need to stringify object before posting to controller!!!

To pass multiple objects to controller, below is the example

Client side javascript

   function getChart() {

        //first json object
        //note: each object Property name must be the same as it is in the Models classes on    server side
        Category = {};
        Category.Name = "Category1";
        Category.Values = [];
        Category.Values[0] = "CategoryValue1";
        Category.Values[1] = "CategoryValue2";

        //second json object
        XAxis = {};
        XAxis.Name = "XAxis1";
        XAxis.Values = [];
        XAxis.Values[0] = "XAxisValue1";
        XAxis.Values[1] = "XAxisValue2";

        //third json object
        YAxis = {};
        YAxis.Name = "YAxis1";

        //convert all three objects to string
        //note: each object name should be the same as the controller parameter is!!
        var StringToPost = JSON.stringify({CategoryObject : Category, XAxisObject : XAxis, YAxisObject : YAxis});

        $.ajax({
            url: "@Url.Action("getChart","SBM")",
            type: 'POST',
            contentType: "application/json",
            dataType: 'html',
            data: StringToPost,
            success: function (data) {
                var imagestring = btoa(data);
                $('#ChartImage').html(data);
            }
        })
    }

MVC Controller

[HttpPost]
public ActionResult getChart(Category CategoryObject, XAxis XAxisObject, YAxis YAxisObject)
{
    //do some stuff with objects here and return something to client
    return PartialView("_Chart");
}

Category model

public class Category
{
    public string Name { get; set; }
    public List<string> Values { get; set; }
}

XAxis model

public class XAxis
{
    public string Name { get; set; }
    public List<string> Values { get; set; }
}

YAxis model

public class YAxis
{
    public string Name { get; set; }
}

Hope it will help someone to clarify the whole picture!

I had same problem (parameter always null), but my solution was different.

Make sure that your ActionResult method parameter doesn't have the same name as the JSON object property.

In this example I renamed myParam to myNewParam to differentiate from MyParam property.

Example: This won't work:

    var myObj = {
        ID: '0',
        MyParam: $('#mycontrol').val(),
    }; 

    $.ajax({
        type: "POST",
        url: '@Url.Action("MyAction", "MyModel")',
        cache: false,
        data: JSON.stringify(myObj),
        datatype: 'json',
        contentType: "application/json; charset=utf-8",
        success: function (result) {
        }
    })

[HttpPost]
        public ActionResult MyAction(Class1 myParam)

This will work:

    var myObj = {
        ID: '0',
        MyParam: $('#mycontrol').val(),
    }; 

    $.ajax({
        type: "POST",
        url: '@Url.Action("MyAction", "MyModel")',
        cache: false,
        data: JSON.stringify(myObj),
        datatype: 'json',
        contentType: "application/json; charset=utf-8",
        success: function (result) {
        }
    })

[HttpPost]
        public ActionResult MyAction(Class1 myNewParam) -->renamed

Looks to me like you're trying to pass an array of objects:

JSONString3 = { HAxis : [{ Name : "monday" }] };

When your action only wants one:

public ActionResult getChart(YAxis HAxis)

Maybe you only meant to pass one?

JSONString3 = { "Name": "monday" };
JSONString3 = { "Name": "monday" };

You should post it to controller as a string, so use JSON.stringify to convert, i dont know how to use your ajax type, i just know to use $.post... T_T

 $.post('@Url.Action("getChart","SBM")', {yourJson : data:JSON.stringify(JSONString3)} , function(data) {
            if (data.success) {
var imagestring = btoa(data.name);
                $('#ChartImage').attr('src', "data:image/png;base64," + imagestring + "?" + new       Date().getTime());
   }
});

In controller,

    public ActionResult getChart(string yourJson)
        {
         YAxis  yAxis= JsonConvert.DeserializeObject<YAxis>(yourValue);
          //  ....... your code here
          return Json(new{success=true,name=yAxis.Name},JsonRequestBehavior.AllowGet);
        }

** Note : JsonConvert is method of using Newtonsoft.Json; , please add Newtonsoft reference.

Adding a datatype attribute to the controller method solved it for me.

[JsonFilter(Param="yourParamName", JsonDataType=typeof(YourParamType))]
[HttpPost]
public ActionResult yourFunction(YourParamType YourParamName)
{
    //do some stuff
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM