【问题标题】:ASP.NET mvc 4 controller parameter always null when sending json to controller, why?将json发送到控制器时,ASP.NET mvc 4控制器参数始终为空,为什么?
【发布时间】:2013-12-04 19:32:16
【问题描述】:

这里已经有一些类似的帖子,并且尝试了所有建议的解决方案,但仍然无法正常工作......我无法在控制器中获取值,它始终为空。下面是代码。我错过了什么吗?

客户端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 控制器

    [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");
    }

型号

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

【问题讨论】:

  • 您是否尝试过以纯文本参数而不是 HAxis 对象的形式发布?
  • 也试过了,也没用。我怀疑它与服务器端的对象名称有关。立即测试...
  • 没有不工作。目前唯一有效的是这种形式的控制器:“public ActionResult getChart(string XAxis)”和以这种形式发布的数据“数据:{“XAxis”:“testValue”}”
  • 我会抓取控制器中的所有内容,然后尝试传递一个字符串值。删除断点并查看该值是否仍为空。如果是这样,您可能会遇到 JS 方面的问题。
  • 好的,我设法得到字符串...但是反序列化到对象仍然不起作用。我是否必须在 Web.config 文件中配置某些内容才能正常工作?

标签: asp.net-mvc json object controller


【解决方案1】:

谢谢大家的指导和解决方案。解决方案是综合了您的所有建议,因此我决定将其汇总在一篇文章中。

问题的解决方法如下:

  1. contentType 应该是 application/json(如上面的 Ant P 建议)
  2. json 数据应该是JSONString3 = {"Name" : "monday" } 的形式(就像上面的 Ant P 建议的那样)
  3. 在发送到控制器之前,json 应该是stringifyed 如下:JSONString3 = JSON.stringify(JSONString3)(正如 Quan 建议的那样)

客户端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 控制器

[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");
}

型号

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

而不是这个:

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

我们可以这样做:

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

但我们仍然需要在发布到控制器之前对对象进行字符串化!!!

要将多个对象传递给控制器​​,下面是示例

客户端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 控制器

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

类别模型

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

XAxis 模型

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

Y轴模型

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

希望它能帮助某人澄清整个情况!

【讨论】:

  • 这个答案对我非常有帮助。谢谢。
  • 对于未来的读者:POST 请求和 GET 请求之间的行为(在 MVC 端)非常不同。在我切换到使用 POST 之前,我的失败(空参数)。
【解决方案2】:

我有同样的问题(参数始终为空),但我的解决方案不同。

确保您的 ActionResult 方法参数的名称与 JSON 对象属性的名称不同。

在此示例中,我将 myParam 重命名为 myNewParam 以区别于 MyParam 属性。

示例: 这行不通:

    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)

这将起作用:

    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

【讨论】:

    【解决方案3】:

    在我看来你正在尝试传递一个对象数组:

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

    当你的行动只想要一个时:

    public ActionResult getChart(YAxis HAxis)
    

    也许你只是想通过一个?

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

    【讨论】:

    • 尝试JSONString3 = { "Name" : "monday" }; 也尝试将您的ContentType 更改为application/json
    • 如果我将 ContentType 更改为 application/json,服务器错误 500
    【解决方案4】:
    JSONString3 = { "Name": "monday" };
    

    你应该把它作为一个字符串发布到控制器,所以使用 JSON.stringify 来转换,我不知道如何使用你的 ajax 类型,我只知道使用 $.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());
       }
    });
    

    在控制器中,

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

    ** 注意:JsonConvert 是使用 Newtonsoft.Json 的方法; ,请添加 Newtonsoft 参考。

    【讨论】:

      【解决方案5】:

      向控制器方法添加数据类型属性为我解决了这个问题。

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

      【讨论】:

      • JsonFilter 不是有效属性。
      猜你喜欢
      • 2015-03-24
      • 2013-01-18
      • 1970-01-01
      • 2013-01-12
      • 1970-01-01
      • 2021-02-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多