将JSON传递给MVC 3操作

8

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

这是我提交到操作的POST内容,地址可以有3个字段或20个字段等等,每次提交都不一样。

更新:我将详细说明一下。我正在尝试使用LinkedIn API,我将收到一个JSON,它看起来像本页面末尾的JSON:链接。我需要创建一个接受此JSON的操作,该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 吗? - Kristof Claes
我刚试过使用FormCollection地址,但它仍然为空。 - Eilimint
你可以在这里使用我的解决方案[1]。简洁易懂。 - Mohsen Afshin
9个回答

5
我不相信没有人说过这个,所以我会尝试。将您的代码设置为以下格式:
 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();

}

通常情况下,您可以将这些可能的属性添加到个人类(或任何其他您可以命名的类)中。但根据linkedin API的要求,由于其复杂性,您需要一个工具来生成数据类。如果您能获取该类的xsd文件(或者您甚至可以从xml生成xsd文件),那么xsd.exe可能会有所帮助。


这根本没有回答问题。你实际上只是回答了“如何创建一个自定义模型来绑定到控制器?”的问题。 - Adam Hess

4
  1. Remove data: JSON.stringify(address) with data: address

  2. Action method

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

正如您所说,您的数据对象可能包含20个道具,为了避免创建20个参数,您可以像下面这样使用form集合

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

我上面的代码只是我在尝试的一个测试,这里是我将要接收的JSON链接link。向下滚动以查看JSON的外观。它将作为JSON从LinkedIn发送,所以我无法控制接收方式。我只需要创建一个操作来接受它。 - Eilimint
如果您删除了“stringify”,那么您发送的内容就不是Json,而只是表单参数。 - Simon_Weaver

2

我不确定这个方法是否有效(我自己从未尝试过),但你可以尝试以下签名:

public ActionResult LinkedIn(dynamic address)

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

其次,当出现这种情况时,一定要检查浏览器是否实际发送了你期望发送到服务器的数据。IE9和Chrome支持此功能,否则可以使用类似Fiddler的工具。

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


1
我知道那有点糟糕 :-( - Simon_Weaver

1

我相信你可以使用 FormCollection 来实现这个功能。

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

我稍微详细解释一下。我正在尝试使用LinkedIn API,我将收到一个JSON,它看起来像这个页面末尾的JSON:链接。我需要创建一个Action,接受这个JSON,这个JSON对于每个人都会有所不同。 - Eilimint

1

你需要将JSON对象包装在你的Action方法中期望的参数名称中。就像这样:

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) {}

1
这是我的做法。我有一个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);
                }
            }
        }
    }

1
可能只是一个打字错误,但你正在调用 GetDetails ActionResult,但你的代码却是 LinkedIn

1
抱歉,那只是一个打字错误,我已经更新了帖子以反映这一点。谢谢。 - Eilimint

1

我的看法是所有答案都有点正确。

因为你不知道要发送的事物数量,所以在服务器上使用formcollection。但是也要从ajax调用中删除stringfy。这意味着数据将使用www-encoding发送。

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


我稍微详细解释一下。我正在尝试使用LinkedIn API,我将收到一个JSON,它看起来像这个页面末尾的JSON:链接。我需要创建一个Action,接受这个JSON,这个JSON对于每个人都会有所不同。 - Eilimint
这可能有帮助吗?http://stackoverflow.com/questions/2849872/using-dynamic-as-type-of-mvc-strongly-typed-view - Simon Halsey
我让FormCollection起作用,但只是通过删除stringfy并将数据作为字符串发送。 然而,我将无法控制数据的发送方式。 我只能接受它作为来自LinkedIn的JSON。 - Eilimint
当您调用MVC操作时,已经从LinkedIn获取了响应JSON。 您可以将其作为字符串发送并在服务器上处理它。 - Simon Halsey

0

你做了太多的工作!你可以直接将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: 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字面量转换为字符串是不必要的。 - Ronald Wildenberg
如果我使用Action参数,它会起作用,但如果有20个以上的参数,事情就会变得混乱,这可能会在未来变得更加复杂。此外,如果发送给我的JSON文字发生变化,那么我的代码将崩溃。 - Eilimint

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接