通过ModelBinding在Web API中将JavaScript对象反序列化为Dictionary<string, string>

3

我有一个简单的 JavaScript 字符串和对象:

var name = "Scarlett Johansson";
var args = { arg1: "foo", arg2: "bar" };

我希望通过$.ajax将它们传递给Web API控制器:

public string Get([FromUri]TestClass input) {
    // would like Args model-bound 
}

我的TestClass如下:

public class TestClass
{
    public string Name { get; set; }
    public Dictionary<string, string> Args { get; set; }
}

Name属性已经按预期绑定,但我没有找到一种方法来绑定Args。我尝试了JSON.stringify(args)、$.param(args),在TestClass上使用List>代替Dictionary,但都没有起作用。
我希望能通过模型绑定来实现这一点,而不是手动反序列化JSON。这可行吗?
澄清:每次调用中"args"的键/值数量会有所变化,因此我需要使用Dictionary。
2个回答

1
默认的模型绑定不会按照那种方式工作,它试图绑定到对象上的公共属性。在这个例子中,你需要一个包含以下内容的类:
public class ArgClass
{
    public string Arg1 { get; set; }
    public string Arg2 { get; set; }
}

public class TestClass
{
    public string Name { get; set; }
    public List<ArgClass> Args { get; set; }
}

另一种选择是编写自定义模型绑定器,或者快速搜索可以找到已经实现的DefaultDictionaryBinder。

https://github.com/loune/MVCStuff/blob/master/Extensions/DefaultDictionaryBinder.cs

更新: 我刚刚意识到你正在使用Web API,这可能略有不同。这篇博客文章解释了Web API的绑定方式: http://blogs.msdn.com/b/jmstall/archive/2012/04/16/how-webapi-does-parameter-binding.aspx

抱歉,我应该明确一下,我的“args”对象会具有不同数量的属性,因此我需要在另一端使用一个字典。我会更新我的问题。 - Darren Mart

0
让我们通过实现(以查看我们传递的结果)来扩展您的方法,就像这样:
public HttpResponseMessage Get([FromUri]TestClass input)
{
    return Request.CreateResponse<TestClass>(HttpStatusCode.OK, input);
}

如果我们想要看到这个:
{
 "Name":"MyName",
 "Args":
  {
   "FirstKey":"FirstValue",
   "SecondKey":"SecondValue"
  }
}

其他话说 testClass.Name == "MyName"testClass.Args["FirstKey"] == "FirstValue"... 我们可以这样调用API:
api/MyService/?name=MyName&args[0].key=FirstKey&args[0].value=FirstValue&args[1].key=SecondKey&args[1].value=SecondValue

参数分行显示,仅为了清晰起见(URI将不包含换行符!):
api/MyService/
  ?name=MyName
  &args[0].key=FirstKey
  &args[0].value=FirstValue
  &args[1].key=SecondKey
  &args[1].value=SecondValue

啊,我明白了,所以我只需要编写一个小函数,遍历 JS 对象的属性,并将该格式附加到带有索引的 URI 中。看起来可行。非常感谢! - Darren Mart

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