将json发送到控制器时,ASP.NET mvc 4控制器参数始终为空,为啥?

Posted

技术标签:

【中文标题】将json发送到控制器时,ASP.NET mvc 4控制器参数始终为空,为啥?【英文标题】: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 文件中配置某些内容才能正常工作? 【参考方案1】:

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

问题的解决方法如下:

    contentType 应该是 application/json(如上面的 Ant P 建议) json 数据应该是JSONString3 = "Name" : "monday" 的形式(就像上面的 Ant P 建议的那样) 在发送到控制器之前,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(newsuccess=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 不是有效属性。

以上是关于将json发送到控制器时,ASP.NET mvc 4控制器参数始终为空,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

无法将 JSON 数据发送到 asp.net MVC 控制器中的另一个操作

ASP.NET Core MVC - 将 HTML 表转换为 json 并使用 ajax 发送到控制器

在 ASP.NET MVC 中设置默认 JSON 序列化程序

如何使用 json 将复杂类型传递给 ASP.NET MVC 控制器

将大型 JSON 对象发布到 ASP.NET MVC

asp.net mvc 控制器返回 json List<T> 未知错误