我正在使用asp.net webapi创建和api 出于某些原因,这个json:
JSON => {"page":"1","count":"10","sorting[name]":"asc"}
JSONString = >"{\"page\":\"1\",\"count\":\"10\",\"sorting[name]\":\"asc\"}"
没有正确地将bindend传递给这样的模型:
public class DataSourceRequestParams
{
public int Page { get; set; }
public int Count { get; set; }
public IDictionary<string, string> Sorting { get; set; }
public IDictionary<string, string> Filter { get; set; }
public IDictionary<string, string> Order { get; set; }
}
Sorting属性没有绑定。
[HttpPost]
public PagingResult<ApplicationUser> Get([FromBody] DataSourceRequestParams @params)
{...}
如果我在MVC应用程序中创建一个动作并传递相同的JSON,它就会被绑定。
我在这里遗漏了什么吗?
答案 0 :(得分:1)
当Content-Type为application / json时,Web API中的绑定需要Dictionary
作为JSON对象,因此以下JSON将与您的模型正确绑定:
{"page":"1","count":"10","sorting":{"name":"asc"}}
修改强>
如果您无法更改传入的JSON,则需要手动将JSON绑定到对象。这里有几个选择。您可以编写自己的IModelBinder
,也可以通过编写自己的JsonConverter
来覆盖JSON活页夹的行为。
作为一个粗略的例子,您可以像这样创建一个JsonConverter
:
public class DictionaryConverter : JsonConverter
{
public DictionaryConverter()
{
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
//I've not implemented writing the Json
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
//create a new object
var temp = new DataSourceRequestParams();
temp.Sorting = new Dictionary<string, string>();
temp.Filter = new Dictionary<string, string>();
temp.Order = new Dictionary<string, string>();
//load the input into a JObject and grab the "simple" values
JObject jsonObject = JObject.Load(reader);
temp.Page = jsonObject["page"].Value<int>();
temp.Count = jsonObject["count"].Value<int>();
//parse the dictionary values
AddValuesToDictionary(temp, jsonObject, "sorting", temp.Sorting);
AddValuesToDictionary(temp, jsonObject, "filter", temp.Filter);
AddValuesToDictionary(temp, jsonObject, "order", temp.Order);
return temp;
}
private void AddValuesToDictionary(DataSourceRequestParams test, JObject jsonObject, string name, IDictionary<string, string> dictionary)
{
//grab each matching property
var properties = jsonObject.Properties().Where(j => j.Name.StartsWith(name));
if (properties != null)
{
foreach (var property in properties)
{
/*for each matched property grab the value between the brackets
* from the name and the property value
* and the associate json value and add it to the dictionary
*/
dictionary.Add(Regex.Match(property.Name, @"\[([^\]]*)\]").Groups[1].Value, property.Value.Value<string>());
}
}
}
public override bool CanConvert(Type objectType)
{
//we can convert if the type is DataSourceRequestParams
return typeof(DataSourceRequestParams).IsAssignableFrom(objectType);
}
}
然后在GlobalConfiguration中注册新转换器:
GlobalConfiguration.Configuration.Formatters.JsonFormatter
.SerializerSettings.Converters.Add(new DictionaryConverter());
然后您的原始JSON将正确解析。显然,代码没有所有错误处理等,所以它不是生产准备好的。