【问题标题】:Pass JSON to MVC 3 Action将 JSON 传递给 MVC 3 操作
【发布时间】:2011-08-12 14:34:12
【问题描述】:

我正在尝试将 JSON 提交给 MVC 操作。我想要的是获取 JSON 对象,然后访问它的数据。 JSON 字段的数量每次都会有所不同,所以我需要一个可以处理所有情况的解决方案。

这是我的帖子,地址可能有 3 个字段或 20 个字段,每个帖子会有所不同。

更新:我会更详细一点。我正在尝试使用 LinkedIn API,我将收到一个类似于本页末尾的 JSON 的 JSON:link。我需要创建一个 Action 来接受这个因人而异的 JSON。

var address =
    {
        Address: "123 rd",   
        City: "Far Away",
        State: "Over There"           
    };


    $.ajaxSetup({ cache: false });
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: "/Account/GetDetails/",
        data: JSON.stringify(address),
        dataType: "json",
        success: function () {

            alert("Success from JS");
        }
    });

这是我在 MVC 中的操作,我需要申请获取传递的任何 JSON 对象并访问其字段。

 [HttpPost]
    public ActionResult GetDetails(object address)
    {         
        //address object comes in as null            

        @ViewBag.Successs = true;

        return View();

    }

【问题讨论】:

  • 您是否尝试过使用FormCollection 而不是object
  • 我刚刚尝试使用 FormCollection 地址,但它仍然为空。
  • 您可以使用我的解决方案 [这里][1]。干净简单 [1]:stackoverflow.com/questions/12069171/…

标签: asp.net asp.net-mvc json asp.net-mvc-3 controller


【解决方案1】:

我不相信没有人这么说,所以我会尝试。有这样的代码

 public class Personal
 {
      public string Address { get; set; }
      public string City { get; set; }
      public string State { get; set; }
      //other properties here
 }

[HttpPost]
public ActionResult GetDetails(Personal address)
{         
    //Should be able to get it.            

    @ViewBag.Successs = true;

    return View();

}

一般来说,您可以将这些可能的属性添加到 Personal 类(或您可以命名的任何名称)中。但是根据linkedin API,由于其复杂性,您将需要一个工具来生成数据类。我认为 xsd.exe 可以帮助您获取 xsd 文件(或者您甚至可以从 xml 生成 xsd 文件)

【讨论】:

  • 这根本没有回答问题。您基本上只是在回答“如何创建自定义模型以绑定到控制器?”的问题
【解决方案2】:
  1. data: address删除data: JSON.stringify(address)

  2. 动作方法

    [HttpPost]
    public ActionResult GetDetails(string Address, string City, string State, string PropName)
    {         
       //access variable here
    }
    

正如您所说,您的数据对象可能包含 20 个道具,为避免创建 20 个参数,您可以使用如下所示的 formscollection

[HttpPost]
public ActionResult GetDetails(FormCollection address)
{        
      string city= address["city"] ;
      string anotherPro=address["prop"];          
}

【讨论】:

  • 我上面的代码只是我正在尝试的一个测试,这里是我将收到link 的 JSON 的链接。向下滚动以查看 JSON 的外观。它将作为 JSON 从 LinkedIn 发送,因此我无法控制如何接收它。我只需要创建一个 Action 来接受它。
  • 如果您要删除 'stringify' 那么您发送的不是 Json - 它只是表单参数。
【解决方案3】:

不确定这是否可行(我自己从未这样做过),但您可以尝试以下签名:

public ActionResult LinkedIn(dynamic address)

我自己其实很感兴趣,想看看接下来会发生什么。或者,正如 Kristof Claes 在评论中所建议的那样,使用FormCollection

其次,当这样的事情发生时,一定要检查浏览器是否真的向服务器发送了你期望的数据。 IE9 和 Chrome 开箱即用支持此功能,否则您可以使用 Fiddler 之类的工具。

编辑:刚刚为自己尝试了dynamic 参数,但不起作用。参数的运行时类型是object,因此您提交的所有内容都丢失了。你最好 使用FormCollection

【讨论】:

  • 是的,我知道这有点糟糕:-(
【解决方案4】:

我相信您可以为此使用FormCollection

public ActionResult LinkedIn(FormCollection address)
{
    var street = address["street"];
    ...
    return View();
}

【讨论】:

  • 我会更详细一点。我正在尝试使用 LinkedIn API,我将收到一个类似于本页末尾的 JSON 的 JSON:link。我需要创建一个 Action 来接受这个因人而异的 JSON。
【解决方案5】:

可能只是一个错字,但您调用的是GetDetails ActionResult,但您的代码是LinkedIn

【讨论】:

  • 对不起,只是一个错字,我更新了帖子以反映这一点。谢谢
【解决方案6】:

您需要将 JSON 对象包装在您期望在操作方法中使用的参数名称中。像这样的:

var data = { address: { address: '123 Test Way', city: 'Parts Unknown', state: 'TX' } };


$.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: "/Account/GetDetails/",
        data: JSON.stringify(data),
        dataType: "json",
        success: function () {

            alert("Success from JS");
        }

然后在您的操作方法中,执行以下操作:

public ActionResult GetDetails(dynamic address) {}

【讨论】:

    【解决方案7】:

    我认为所有的答案都是正确的。

    由于您不知道要发送的内容数量,请在服务器上使用 formcollection。但也要从 ajax 调用中删除 stringfy。这意味着数据将使用 www-encoding 发送。

    如果要发送 n 个地址对象,请将 mvc 操作参数更改为地址对象数组并使用 stringfy。

    【讨论】:

    • 我会更详细一点。我正在尝试使用 LinkedIn API,我将收到一个 JSON,它看起来像本页末尾的 JSON:link。我需要创建一个 Action 来接受这个因人而异的 JSON。
    • 这可能有帮助吗? stackoverflow.com/questions/2849872/…
    • 我让 FormCollection 工作,但只能通过删除 stringfy 并将数据作为字符串发送。但是,我无法控制数据的发送方式。我只需要接受它作为来自 LinkedIn 的 JSON
    • 当您调用 mvc 操作时,您已经从 LinkedIn 获得了响应 json。您可以将其作为字符串发送并在服务器上进行处理。
    【解决方案8】:

    这就是我的做法。我有一个 MyProject.Model.Entities 并通过在给定的操作方法上使用 [ParamSerializationFilter] 属性将它们序列化。

    完整代码在这里:https://gist.github.com/3b18a58922fdd8d5a963

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (!Enum.GetNames(typeof(AllowedMethods)).Any(n => n == filterContext.HttpContext.Request.HttpMethod))
                throw new InvalidOperationException("Invalid Request: HttpMethod");
    
            foreach (var param in filterContext.ActionDescriptor.GetParameters())
            {
                if (ModelTypes.Contains(param.ParameterType))
                {
                    if ((filterContext.HttpContext.Request.ContentType ?? string.Empty) == ("application/json"))
                    {
                        filterContext.ActionParameters[param.ParameterName] =
                            JsonSerializer.DeserializeFromStream(param.ParameterType, filterContext.HttpContext.Request.InputStream);
                    }
                    else if (filterContext.HttpContext.Request.ContentType.Contains("xml"))
                    {
                        filterContext.ActionParameters[param.ParameterName] =
                        XmlSerializer.DeserializeFromStream(param.ParameterType, filterContext.HttpContext.Request.InputStream);
                    }
                }
            }
        }
    

    【讨论】:

      【解决方案9】:

      你做的太多了!您可以将 JSON Literal 直接传递给服务器并通过操作方法参数访问元素,如下所示:

      var address =
          {
              Address: "123 rd",   
              City: "Far Away",
              State: "Over There"           
          };
      
      
          $.ajaxSetup({ cache: false });
          $.ajax({
              type: "POST",
              contentType: "application/json; charset=utf-8",
              url: "/Account/GetDetails/",
              data: address,
              dataType: "json",
              success: function () {
      
                  alert("Success from JS");
              }
          });
      
      [HttpPost]
          public ActionResult LinkedIn(string Address, string City, string State)
          {                    
              // now you have everything you want as params
              @ViewBag.Successs = true;
      
              return View();
      
          }
      

      注意:仅当您的操作参数的名称与您的 JSON 文字属性完全相同时,这才有效。

      【讨论】:

      • 但要求是参数的数量可以从 3 到 20 不等。与其使用 20 参数的操作方法,我宁愿使用FormCollection。您说没有必要将 JSO 文字转换为字符串是正确的。
      • 如果我使用 Action 参数,它会起作用,但如果我有 20 多个参数,事情会变得混乱,这可能会在未来变得更多。此外,如果 JSON 文字发送给我在哪里更改,那么我的代码将会崩溃。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-24
      • 1970-01-01
      • 2014-07-04
      • 1970-01-01
      • 2012-06-02
      • 2012-10-17
      相关资源
      最近更新 更多