2014-06-25 56 views
0

我有一个C#网站和Web API与Save-method结合在一个API控制器中。此方法只允许HttpPosts。我想要发送的正文是List<int>,List<decimal>longJSON正文到列表<int>,列表<decimal>和长

因为API控制器中的HttpPost方法只允许一个参数工作,所以我尝试了JObjectstring作为参数。当我使用字符串时,它始终为空,当我使用JObject它不是null,但从正文中不正确地复制。由于这些内容为空且不正确地复制,因此转换为List<int>List<decimal>long也不起作用。


参数为字符串:

[HttpPost] 
[AllowAnonymous] 
[ActionName("save")] 
public bool SaveOrders([FromBody] string jsonData) 
{ 
    // Convert jsonData string to List<int>, List<decimal>, long 
    JObject json = JObject.Parse(jsonData); 
    List<int> productIds = JsonConvert.DeserializeObject(json["productIds"].ToString(), typeof(List<int>)); 
    List<decimal> prices = JsonConvert.DeserializeObject(json["prices"].ToString(), typeof(List<decimal>)); 
    long dateInTicks = JsonConvert.DeserializeObject(json["dateInTicks"].ToString(), typeof(long)); 

    ... 
} 

与POST体:

"{ 
    "productIds": "[20, 25]", 
    "prices": "[0.40, 7.40]", 
    "dateInTicks": "1402444800" 
}" 

当我调试这上面,参数字符串总是空。


参数作为JObject:

[HttpPost] 
[AllowAnonymous] 
[ActionName("save")] 
public bool SaveOrders([FromBody] JObject jsonData) 
{ 
    // Convert jsonData JObject to List<int>, List<decimal>, long 
    dynamic json = jsonData; 
    string sProductIds = (string)json["productIds"]; 
    string sPrices = (string)json["prices"]; 
    string sDateInTicks = (string)json["dateInTicks"]; 
    List<int> productIds = JsonConvert.DeserializeObject(sProductIds, typeof(List<int>)); 
    List<decimal> prices = JsonConvert.DeserializeObject(sPrices, typeof(List<decimal>)); 
    long dateInTicks = JsonConvert.DeserializeObject(sDateInTicks, typeof(long)); 

    ... 
} 

与POST体:

productIds: "[20, 25]", 
prices: "[0.40, 7.40]", 
dateInTicks: "1402444800" 

当调试此,参数-JObject是:

{ 
    "productIds: \"": { 
    "20, 25]\",\nprices: \"": { 
     "0.40, 7.40]\",\ndateInTicks: \"1402444800\"": "" 
    } 
    } 
} 

和sProductIds,sPrices和sDateInTicks为空。


我知道我在做一些错误的事情,所以这个问题,因为我不怎么应该改变它。


编辑1(拉法尔的建议):

在我的配置文件,我添加一行:

// Only allow JSON response format 
var json = config.Formatters.JsonFormatter; 
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects; 
config.Formatters.Remove(config.Formatters.XmlFormatter); 
// Added the following line: 
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

而且我的方法是改变:

[HttpPost] 
[AllowAnonymous] 
[ActionName("save")] 
public bool SaveOrders([FromBody] Data jsonData) 
{ 
    if (jsonData != null) 
    { 
     if (jsonData.productIds != null && jsonData.prices != null) 
     { 
      return SavePrices(jsonData.productIds, jsonData.prices, jsonData.dateInTicks); 
     } 
     else 
     { 
      Console.WriteLine("One of the objects is null, so we can't continue."); 
      return false; 
     } 
    } 
    else 
    { 
     Console.WriteLine("The send data is null, so we can't continue."); 
     return false; 
    } 
} 

public class Data 
{ 
    public List<int> productIds { get; set; } 
    public List<decimal> prices { get; set; } 
    public long dateInTicks { get; set; } 
} 

不过,尽管数据参数不为null,它们的列表都是且其长度也是0。


编辑2:

随着Firefox的RESTClient实现主体:

"productIds":[20,25],"prices":[0.4,7.4],"dateInTicks":1402444800 

为什么JObject参数如下:

{ 
    "\"productIds\":": { 
    "20,25],\"prices\":": { 
     "0.4,7.4],\"dateInTicks\":1402444800": "" 
    } 
    } 
} 

,而不是这样的:

{ 
    \"productIds\":[20,25],\"prices\":[0.4,7.4],\"dateInTicks\":1402444800 
} 

它会自动删除第一[与阵列或:" {"替换它..

回答

0

添加类:

public class Data 
{ 
    public List<int> productIds { get; set; } 
    public List<decimal> prices { get; set; } 
    public long dateToTicks { get; set; } 
} 

并更改API的方法的签名接受它作为参数。

请注意,属性名称是pascal大小写。我是这么做的,因为反序列化程序的默认配置将不允许骆驼案例。为了处理您的JSON和使用“正常”的性质套管添加:在您的站点配置文件

  config.Formatters.JsonFormatter.SerializerSettings.ContractResolver 
= new CamelCasePropertyNamesContractResolver(); 

行,你会发现它在App_Start文件夹新模板或直接在Global.asax.cs。 配置类型为HttpConfiguration


进一步的调查使我你已经无效的(以及不是无效尽可能JSON验证而言,但手头没有合适的任务)的JSON内容的结论。如果您发布它:

{ 
    "productIds": [20, 25], 
    "prices": [0.40, 7.40], 
    "dateToTicks": "1402444800" 
} 

没有任何额外的报价,然后它会反序列化到数据类。如果你需要保留它,那么你需要反序列化,就好像你松散的包装报价,然后你有3个字符串属性而不是值列表的json对象。

+0

我试过你说的,虽然数据参数本身不为空,'List ','List '都是,而'long'也是0. –

+0

我已经添加了“Edit 1“的主要职位了解更多的细节。 –

+0

你的json和你发布的一样吗?我将这些报价视为无效。 – Rafal