将 JSON 传递给 MVC 3 操作

发布于 2024-11-29 19:46:56 字数 979 浏览 6 评论 0原文

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

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

更新:我将详细介绍一下。我正在尝试使用 LinkedIn API,我将收到一个 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();

    }

I am trying to submit JSON to a MVC action. What I want is to take the JSON object and then access it's data. The number of JSON fields will vary each time so I need a solution that will handle all cases.

This is my POST to my action, address could have 3 fields or 20 it will vary on each post.

Update: I'll go into a little more detail. I'm trying to use the LinkedIn API, I'll be sent a JSON which will look like the JSON at the end of this page : link. I need to create an Action which will accept this JSON which will vary for every person.

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

This is my action in MVC, I need to be apply to take whatever JSON object is passed and access its fields.

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

        @ViewBag.Successs = true;

        return View();

    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

℡Ms空城旧梦 2024-12-06 19:46:57
  1. 删除 data: JSON.stringify(address)data: address

  2. 操作方法

    <前><代码>[HttpPost]
    公共 ActionResult GetDetails(字符串地址,字符串城市,字符串州,字符串 PropName)
    {
    //这里访问变量
    }

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

[HttpPost]
public ActionResult GetDetails(FormCollection address)
{        
      string city= address["city"] ;
      string anotherPro=address["prop"];          
}
  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
    }
    

As you have said your data object may contain 20 props, to avoid creating 20 parameters, you can use formscollection like below

[HttpPost]
public ActionResult GetDetails(FormCollection address)
{        
      string city= address["city"] ;
      string anotherPro=address["prop"];          
}
春风十里 2024-12-06 19:46:57

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

public ActionResult LinkedIn(dynamic address)

我自己实际上很感兴趣,想看看接下来会发生什么。或者,按照 Kristof Claes 的评论中的建议,使用 FormCollection

其次,当发生这种情况时,请务必检查浏览器是否确实向服务器发送了您期望的数据。 IE9 和 Chrome 开箱即用地支持此功能,否则您可以使用 Fiddler 等工具。

编辑:我自己尝试使用dynamic参数,但这不起作用。参数的运行时类型是object,所以你的一切提交丢失。你最好
使用FormCollection

Not sure if this will work (never done this myself), but you could try the following signature:

public ActionResult LinkedIn(dynamic address)

I'm actually quite interested myself to see what will happen then. Or, as suggested in the comment by Kristof Claes, use a FormCollection.

Second, when things like this happen, always check whether the browser actually sends the data you expected to the server. IE9 and Chrome support this out of the box, otherwise you can use a tool like Fiddler.

EDIT: Just tried for myself with a dynamic parameter and that doesn't work.. The runtime type of the parameter is object so everything you submitted is lost. You'd better
use FormCollection.

情仇皆在手 2024-12-06 19:46:57

我相信您可以使用 FormCollection 来实现此目的。

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

I believe you can use a FormCollection for this.

public ActionResult LinkedIn(FormCollection address)
{
    var street = address["street"];
    ...
    return View();
}
风流物 2024-12-06 19:46:57

可能只是一个拼写错误,但您正在调用 GetDetails ActionResult,但您的代码是 LinkedIn

Might just be a typo, but you are calling GetDetails ActionResult, but yet your code is LinkedIn ?

内心荒芜 2024-12-06 19:46:57

您需要将 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) {}

You need to wrap your JSON object in the name of parameter you are expecting in your action method. Something like this:

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

Then in your action method, do this:

public ActionResult GetDetails(dynamic address) {}
枫林﹌晚霞¤ 2024-12-06 19:46:57

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

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

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

My take is all the answers are sort of right.

As your don't know the number of things you're sending, use formcollection on the server. But also remove the stringfy from the ajax call. These means the data will be sent using www-encoding.

If you wnat to send n address objects, change the mvc action parameter to an array of address objects and use stringfy.

念三年u 2024-12-06 19:46:57

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

This is how I do it. I have a MyProject.Model.Entities and I serialize them in by using [ParamSerializationFilter] attribute on the given action method.

Full code here: 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);
                }
            }
        }
    }
谢绝鈎搭 2024-12-06 19:46:57

你做的工作太多了!您可以将 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 Literal 属性完全相同时,这才有效。

You're doing too much work! You can pass the JSON Literal directly to the server and access the elements via the action method parameters, like this:

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();

    }

Note: This will only work if your action params are named the exact same as your JSON Literal attributes.

许久 2024-12-06 19:46:56

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

 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 文件(或者您甚至可以从 xml 生成 xsd 文件),xsd.exe 可以提供帮助

I don't believe nobody saying this so I will try. Have your code like this

 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();

}

In general, you can add those possible properties into the class Personal (or whatever you can name it). But according to linkedin API, you will need a tool to generate the data class due to its complexity. I think xsd.exe can help if you can get xsd file for that (or you can even generate xsd file from xml)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文