我如何传递一个字典作为参数,从jQuery的/阿贾克斯一个ActionResult方法? [英] How do I pass a Dictionary as a parameter to an ActionResult method from jQuery/Ajax?
问题描述
我使用jQuery做一个Ajax调用使用HTTP POST在ASP.NET MVC中。我希望能够传递值的词典。
我能想到的最接近的是要传递一个多维字符串数组,但实际上被传递到的ActionResult方法的结果是单维的字符串数组包含键/值的字符串连接对。
例如,在下面的值数组中的第一项包含以下值:
标识,200
下面是我的ActionResult方法的一个例子:
公众的ActionResult为addItems(字符串[]值)
{
// 做一点事
}
这里有一个如何我打电话从jQuery的方法的一个例子:
$。员额(/控制器/ addItems的,
{
价值观:
[ID,200],
[名字,克里斯],
[DynamicItem1,一些价值],
[DynamicItem2,其他值]
]
},
功能(数据){},
JSON);
有谁知道如何从jQuery的传递Dictionary对象的ActionResult的方法,而不是数组?
我真的想这样定义我的ActionResult:
公众的ActionResult为addItems(词典<字符串,对象>的值)
{
// 做一点事
}
有什么建议?
更新:我试图传递一个逗号值的范围内,它基本上只是使得它不可能实际使用字符串解析解析键/值对
通过这个:
值:
[ID,200,300],
[名字,克里斯]
]
结果是:
值[0] =号,200,300;
值[1] =名字,克里斯;
最后,我想通了!感谢您的建议吧!我终于想通了最佳的解决方案是通过HTTP POST通过JSON和使用自定义模型绑定器的JSON转换为一个字典。有一件事我在我的解决方案所做的就是创建一个JsonDictionary对象,从字典继承,这样我可以将自定义模型绑定器的JsonDictionary类型,它不会导致在未来任何冲突,如果我使用字典作为一个ActionResult的参数以后的不同的目的JSON。
下面是最终的ActionResult方式:
公众的ActionResult为addItems([绑定(包括=值)JsonDictionary值)
{
// 做一点事
}
和jQuery的$。员额电话:
$。员额(/控制器/ addItems的,
{
值:Sys.Serialization.JavaScriptSerializer.serialize(
{
ID:200,
名:克里斯
}
)
},
功能(数据){},
JSON);
然后JsonDictionaryModelBinder需要注册,我已将此添加的Global.asax.cs中的Application_Start方法:
保护无效的Application_Start()
{
ModelBinders.Binders.Add(typeof运算(JsonDictionary),新JsonDictionaryModelBinder());
}
和,终于在这里是我创建的JsonDictionaryModelBinder对象和JsonDictionary对象:
公共类JsonDictionary:字典<字符串,对象>
{
公共JsonDictionary(){}
公共无效添加(JsonDictionary jsonDictionary)
{
如果(jsonDictionary!= NULL)
{
的foreach(在jsonDictionary.Keys变种K)
{
this.Add(K,jsonDictionary [K]);
}
}
}
}
公共类JsonDictionaryModelBinder:IModelBinder
{
#地区IModelBinder会员
公共对象BindModel(ControllerContext controllerContext,ModelBindingContext的BindingContext)
{
如果(bindingContext.Model == NULL){bindingContext.Model =新JsonDictionary(); }
VAR模型= bindingContext.Model为JsonDictionary;
如果(bindingContext.ModelType == typeof运算(JsonDictionary))
{
//反序列化中的includeProperties规定每个窗体/查询字符串项
//传递给的UpdateModel方法调用的参数
//检查/添加表格收集
this.addRequestValues(
模型,
controllerContext.RequestContext.HttpContext.Request.Form,
controllerContext,BindingContext中);
//检查/添加QueryString集合
this.addRequestValues(
模型,
controllerContext.RequestContext.HttpContext.Request.QueryString,
controllerContext,BindingContext中);
}
回归模型;
}
#endregion
私人无效addRequestValues(JsonDictionary模型,NameValueCollection中的NameValueCollection,ControllerContext controllerContext,ModelBindingContext的BindingContext)
{
的foreach(在nameValueCollection.Keys字符串键)
{
如果(bindingContext.PropertyFilter(键))
{
VAR jsonText =的NameValueCollection [关键];
VAR newModel,并向= deserializeJson(jsonText);
//添加新的JSON键/值对示范
model.Add(newModel,并向);
}
}
}
私人JsonDictionary deserializeJson(JSON字符串)
{
//必须引用System.Web.Extensions程序,以使用JavaScriptSerializer
无功序列化=新System.Web.Script.Serialization.JavaScriptSerializer();
返回serializer.Deserialize< JsonDictionary>(JSON);
}
}
I'm using jQuery to make an Ajax call using an Http Post in ASP.NET MVC. I would like to be able to pass a Dictionary of values.
The closest thing I could think of was to pass in a multi-dimensional array of strings, but the result that actually gets passed to the ActionResult method is a single dimensional string array containing a string concatenation of the "key/value" pair.
For instance the first item in the below "values" array contains the below value:
"id,200"
Here's an example of my ActionResult method:
public ActionResult AddItems(string[] values)
{
// do something
}
Here's an example of how I'm calling the method from jQuery:
$.post("/Controller/AddItems",
{
values: [
["id", "200"],
["FirstName", "Chris"],
["DynamicItem1", "Some Value"],
["DynamicItem2", "Some Other Value"]
]
},
function(data) { },
"json");
Does anyone know how to pass a Dictionary object from jQuery to the ActionResult method instead of an Array?
I would really like to define my ActionResult like this:
public ActionResult AddItems(Dictionary<string, object> values)
{
// do something
}
Any suggestions?
UPDATE: I tried passing in a comma within the value and it basically just makes it impossible to actually parse the key/value pair using string parsing.
Pass this:
values: [
["id", "200,300"],
["FirstName", "Chris"]
]
results in this:
values[0] = "id,200,300";
values[1] = "FirstName,Chris";
At last I figured it out!! Thanks for the suggestions everyone! I finally figured out the best solution is to pass JSON via the Http Post and use a custom ModelBinder to convert the JSON to a Dictionary. One thing I did in my solution is created a JsonDictionary object that inherits from Dictionary so that I can attach the custom ModelBinder to the JsonDictionary type, and it wont cause any conflicts in the future if I use Dictionary as a ActionResult parameter later on for a different purpose than JSON.
Here's the final ActionResult method:
public ActionResult AddItems([Bind(Include="values")] JsonDictionary values)
{
// do something
}
And the jQuery "$.post" call:
$.post("/Controller/AddItems",
{
values: Sys.Serialization.JavaScriptSerializer.serialize(
{
id: 200,
"name": "Chris"
}
)
},
function(data) { },
"json");
Then the JsonDictionaryModelBinder needs to be registered, I added this to the Application_Start method within the Global.asax.cs:
protected void Application_Start()
{
ModelBinders.Binders.Add(typeof(JsonDictionary), new JsonDictionaryModelBinder());
}
And, finally here's the JsonDictionaryModelBinder object and JsonDictionary object I created:
public class JsonDictionary : Dictionary<string, object>
{
public JsonDictionary() { }
public void Add(JsonDictionary jsonDictionary)
{
if (jsonDictionary != null)
{
foreach (var k in jsonDictionary.Keys)
{
this.Add(k, jsonDictionary[k]);
}
}
}
}
public class JsonDictionaryModelBinder : IModelBinder
{
#region IModelBinder Members
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext.Model == null) { bindingContext.Model = new JsonDictionary(); }
var model = bindingContext.Model as JsonDictionary;
if (bindingContext.ModelType == typeof(JsonDictionary))
{
// Deserialize each form/querystring item specified in the "includeProperties"
// parameter that was passed to the "UpdateModel" method call
// Check/Add Form Collection
this.addRequestValues(
model,
controllerContext.RequestContext.HttpContext.Request.Form,
controllerContext, bindingContext);
// Check/Add QueryString Collection
this.addRequestValues(
model,
controllerContext.RequestContext.HttpContext.Request.QueryString,
controllerContext, bindingContext);
}
return model;
}
#endregion
private void addRequestValues(JsonDictionary model, NameValueCollection nameValueCollection, ControllerContext controllerContext, ModelBindingContext bindingContext)
{
foreach (string key in nameValueCollection.Keys)
{
if (bindingContext.PropertyFilter(key))
{
var jsonText = nameValueCollection[key];
var newModel = deserializeJson(jsonText);
// Add the new JSON key/value pairs to the Model
model.Add(newModel);
}
}
}
private JsonDictionary deserializeJson(string json)
{
// Must Reference "System.Web.Extensions" in order to use the JavaScriptSerializer
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
return serializer.Deserialize<JsonDictionary>(json);
}
}
这篇关于我如何传递一个字典作为参数,从jQuery的/阿贾克斯一个ActionResult方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!