我正在尝试在MVC6控制器中接收JSON。我看到我的函数在调试时被触发,但是param总是为空。
JSON就像这样(它来自外部软件,所以我无法改变它。还要注意ContentType是“application / w-xxx-form-urlencoded”):
["String1","String2",["StringInAList1","StringInAList2",...]]
我的代码如下所示:
[HttpPost]
public void ReceiveJson([FromBody] MyJson json)
{
//stuff
}
public class MyJson
{
public string string1 { get; set; }
public string string2 { get; set; }
public List<string> Data { get; set; }
}
这里有什么问题吗?
答案 0 :(得分:1)
首先,JSON是一个数组,而不是一个对象。 JSON对象看起来像这样
{ "MessageName": "String1", "UserName": "String2", "AdditionalData": ["StringInAList1","StringInAList2",...] }
由于不可枚举的c#类映射到JSON对象,因此asp.net默认情况下无法将该JSON反序列化到您的类中。
其次,通过文档here,AdditionalData
可以是任何字符串数组或相同类型的嵌套数组,而不仅仅是一个简单的字符串数组,例如:
["GameEnded","Risterral",[["Risterral", "Won"],["PlayerName2", "Lost"]]]
一个简单的List<string> Data
无法代表这一点。
从asp.net uses Json.NET by default for JSON serialization开始,表示这种多态数组的最简单方法是JArray
,它可以表示内存中的任何JSON数组。您还需要custom JsonConverter
作为顶级对象。因此:
public enum HexRequestType
{
Unknown,
Login,
Logout,
SaveDeck,
DraftPack,
DraftCardPicked,
GameStarted,
GameEnded,
Collection,
}
[JsonConverter(typeof(HexRequestConverter))]
public class HexRequest
{
[JsonIgnore]
public HexRequestType RequestType
{
get
{
if (string.IsNullOrEmpty(MessageName))
return HexRequestType.Unknown;
if (MessageName.Equals("DaraftCardPicked", StringComparison.OrdinalIgnoreCase))
return HexRequestType.DraftCardPicked;
try
{
return (HexRequestType)Enum.Parse(typeof(HexRequestType), MessageName, true);
}
catch (Exception)
{
Debug.WriteLine("Unknown request " + MessageName);
return HexRequestType.Unknown;
}
}
}
public string MessageName { get; set; }
public string UserName { get; set; }
public JArray AdditionalData { get; set; }
}
public class HexRequestConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(HexRequest);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var array = JToken.Load(reader) as JArray;
if (array == null)
return existingValue;
var request = existingValue as HexRequest ?? new HexRequest();
request.MessageName = (array.Count > 0 ? (string)array[0] : null);
request.UserName = (array.Count > 1 ? (string)array[1] : null);
request.AdditionalData = (JArray)(array.Count > 2 ? array[2] : null) ?? new JArray();
if (array.Count > 3)
{
Debug.WriteLine("array too large");
throw new InvalidOperationException();
}
return request;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var request = (HexRequest)value;
var list = new List<object> { request.MessageName, request.UserName, request.AdditionalData };
serializer.Serialize(writer, list);
}
}
完成后,您可以使用Linq和Linq-to-JSON手动提取预期数据,例如:
switch (request.RequestType)
{
case HexRequestType.GameEnded:
{
// ["GameEnded","Risterral",[["Risterral", "Won"],["PlayerName2", "Lost"]]]
var results = request.AdditionalData.OfType<JArray>().Select(a => new { Player = (string)a[0], Result = (string)a[1] }).ToList();
Debug.WriteLine(JsonConvert.SerializeObject(results));
// Outputs [{"Player":"Risterral","Result":"Won"},{"Player":"PlayerName2","Result":"Lost"}]
}
break;
// Other cases as needed
default:
break;
}