将 JSON 数据传递给控制器​​方法而无需声明对象

Posted

技术标签:

【中文标题】将 JSON 数据传递给控制器​​方法而无需声明对象【英文标题】:Passing JSON Data Into A Controller Method Without Having To Declare An Object 【发布时间】:2013-01-29 05:43:59 【问题描述】:

我正在使用 ASP.NET MVC 和 jQuery 通过 AJAX 调用保存一些数据。我目前使用像这样的 jQuery ajax() 函数传入一些 JSON 数据

$.ajax(
    dataType: 'json',
    type: 'POST',
    url: '@Url.Action("UpdateName", "Edit")',
    data: 
        id: 16,
        name: 'Johnny C. Bad'
    
);

使用这个控制器方法和辅助类。

public void UpdateName(Poco poco)

    var person = PersonController.GetPerson(poco.Id);   
    person.Name = poco.Name;
    PersonController.UpdatePerson(person);


public class Poco

    public int Id  get; set; 
    public string Name  get; set; 

另一种接受 JSON 数据的方法是简单地使用多个参数,像这样

public void UpdateName(int id, string name)

    var person = PersonController.GetPerson(id);    
    person.Name = name;
    PersonController.UpdatePerson(person);

这种方法适用于较少数量的参数,但我的真实世界代码通常有大约 5 到 10 个参数。使用对象而不是必须声明和使用所有这些参数非常方便。

我想知道是否有另一种方法可以将 JSON 数据作为单个对象接受,而不必为我想使用这种方法的每个控制器方法声明一个类。例如,像这样:

public void UpdateName(dynamic someData)

    var person = PersonController.GetPerson(someData.Id);   
    person.Name = someData.Name;
    PersonController.UpdatePerson(person);

【问题讨论】:

您当然可以发布复杂的对象,只要将它们转换为 JSON。您是使用 jscript 还是从 Razor 变量构建复杂对象? 另一种选择是将 json 数据作为字符串接收并在操作中反序列化。 ***.com/questions/11608026/… 对象来自一个 javascript 对象。 【参考方案1】:

你可以接受一个 FormCollection,它看起来像:

public void UpdateName(FormCollection collection)

    var person = PersonController.GetPerson(int.Parse(collection["id"]));
    person.Name = collection["name"];
    person.Age = collection["age"];

    PersonController.UpdatePerson(person);

【讨论】:

【参考方案2】:

可能的解决方案

创建特定的模型绑定器,例如作为



    public class DynamicModelBinder : DefaultModelBinder
    
        public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        
            if (controllerContext.HttpContext.Request.Form.AllKeys.Any(x => x == "dynamic"))
            
                dynamic model = new ExpandoObject();
                IDictionary underlyingmodel = model;

                foreach (var key in controllerContext.HttpContext.Request.Form.AllKeys)
                    underlyingmodel.Add(key, (bindingContext.ValueProvider.GetValue(key).RawValue as string[]).First());

                return model;
            

            return base.BindModel(controllerContext, bindingContext);
        
    

此绑定器将检查名称为“动态”的特定输入,然后创建动态对象



    public ActionResult Index()
    
       return View();
    

    [HttpPost]
    public ActionResult Index(dynamic input)
    
       ViewBag.Result = input.phrase;
       return View();
    

【讨论】:

【参考方案3】:

我不太清楚你为什么要实现它,但你可以使用动态来实现它(我没有尝试过):

public void UpdateName(string parameters)

    var dynamicObject = Json.Decode(parameters);

Json.Decode 在 System.Web.Healpers 命名空间中

你可以通过 javascript 传递它们,如下所示:

var dataObject = JSON.stringify( id: '1', name: 'John' );
$.ajax(
    dataType: 'json',
    type: 'POST',
    url: '@Url.Action("UpdateName", "Edit")',
    data: dataObject 
);

【讨论】:

【参考方案4】:

我想这里的问题是确切地知道您希望在控制器中在实体之间共享哪些常见功能。如果所有这些功能都可以在某个共享属性后面统一(从上面的示例中,可能是 Id 和 Name 字段?)那么您可以来回传递 IEntity 的实例,或者包含这两个属性的某个基类。

【讨论】:

以上是关于将 JSON 数据传递给控制器​​方法而无需声明对象的主要内容,如果未能解决你的问题,请参考以下文章

如何使用json将数据传递给ajax函数?

制作某种具有多行的行构建器并将 JSON 数据传递给其中的最佳方法是啥。扑

将信用卡数据传递给控制器

创建 json 对象并使用 VBScipt 将数据传递给服务器

如何将集合视图数据传递给新的视图控制器

将 Json 数据传递给handsontable