CamelCase JSON WebAPI 子对象(嵌套对象、子对象)
Posted
技术标签:
【中文标题】CamelCase JSON WebAPI 子对象(嵌套对象、子对象)【英文标题】:CamelCase JSON WebAPI Sub-Objects (Nested objects, child objects) 【发布时间】:2014-06-15 17:49:25 【问题描述】:我正在创建一个复杂对象,其中包含要从我的 Web api 控制器返回的子对象(嵌套对象)。该对象包含其他对象类型的列表。列表中的这些子对象类型遵循 .NET 中使用的帕斯卡大小写。
var persons = peopleLookup.Values;
var users = userLookup.Values;
var roles = rolesLookup.Values;
var groups = groupLookup.Values;
var roleAssignments = roleAssignmentLookup.Values;
var groupMembers = groupMemberLookup.Values;
return new persons, users, roles, roleAssignments, groups, groupMembers ;
我的问题是 WebAPI 不会对子项目的每个属性进行驼峰式大小写。例如,persons 列表中的第一个人应该具有 id、name 的属性,而不是 .NET pascal 大小写的 Id、Name。这同样适用于所有其他子项目。
【问题讨论】:
我也有同样的问题。你弄明白了吗? 【参考方案1】:您可以配置 JSON.NET 以在应用程序启动时生成驼峰式名称。来自Scott Allen's post的代码sn-p:
var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
【讨论】:
【参考方案2】:我遇到了同样的问题。我正在返回一个用于网格填充的对象。它具有一些属性,如行、页、总计等。将合同解析器设置为驼峰式案例可以解决顶层属性的问题。但是,如果任何属性包含属性名称为 pascal 大小写的对象列表,它不会改变它们的大小写。
这就是我为解决这个问题所做的工作。
带有要返回的数据的网格对象
[DataContract]
public class GridProperties<T>
[DataMember]
public List<T> Rows get; set;
[DataMember]
public int Records get; set;
[DataMember]
public int Total get; set;
[DataMember]
public int Page get; set;
Here Rows 保存对象列表。在这里,我返回了模型对象列表。模型类看起来像:
public class ClientListModel
[DataMember(Name = "clientId")]
public int ClientId get; set;
[DataMember(Name = "firstName")]
public string FirstName get; set;
[DataMember(Name = "lastName")]
public string LastName get; set;
[DataMember(Name = "startDate")]
public DateTime? StartDate get; set;
[DataMember(Name = "status")]
public string Status get; set;
public ClientListModel()
下面是我如何从我的 API 控制器返回 JSON 数据
[HttpGet]
public GridProperties<ClientListModel> GetClients(int page)
const int rowsToDisplay = 10;
try
IEnumerable<ClientListModel> clientList = null;
using (var context = new AngularModelConnection())
clientList = context.Clients.Select(i => new ClientListModel()
ClientId = i.Id,
FirstName = i.FirstName,
LastName = i.LastName,
StartDate = i.StartDate,
Status = (i.DischargeDate == null || i.DischargeDate > DateTime.Now) ? "Active" : "Discharged"
);
int total = clientList.Count(); //Get count of total records
int totalPages = Convert.ToInt16(Math.Ceiling((decimal) total/rowsToDisplay)); //Get total page of records
return new GridProperties<ClientListModel>
Rows = clientList.Skip((page - 1)*rows).Take(rows).ToList(),
Records = total,
Total = totalPages,
Page = page
;
catch (Exception exc)
ExceptionLogger.LogException(exc);
return new GridProperties<ClientListModel>
Rows = null,
Records = 0,
Total = 0,
Page = page
;
[DataMember(Name ="")]
属性指定当对象被序列化时该属性使用什么名称。
希望这会有所帮助!
【讨论】:
【参考方案3】:在尝试从 WebAPI 返回具有关系的 DataSet 时,我遇到了与嵌套对象类似的问题。使用ExpandoObject
对我有用,也许这会对你有所帮助。
private static object ConvertDataSetWithRelationsToCamelCaseObject(DataSet ds)
foreach (DataRelation relation in ds.Relations)
relation.Nested = true;
var doc = new XmlDocument();
doc.LoadXml(ds.GetXml());
var pascalCaseJson = JsonConvert.SerializeXmlNode(doc, Formatting.None, true);
var pascalCaseObject = JsonConvert.DeserializeObject<ExpandoObject>(pascalCaseJson);
var camelCaseJson = JsonConvert.SerializeObject(pascalCaseObject, Formatting.Indented,
new JsonSerializerSettings ContractResolver = new CamelCasePropertyNamesContractResolver(),);
return JsonConvert.DeserializeObject(camelCaseJson);
使用关系创建数据集的示例代码:
var dsTasks = new Tasks().Find(sqlParameters);
var dsValidators = new Validators().Find(sqlParameters);
var dsProperties = new ValidatorProperties().Find(sqlParameters);
dsTasks.Tables[0].TableName = "Tasks";
dsValidators.Tables[0].TableName = "Validators";
dsProperties.Tables[0].TableName = "ValidatorProperties";
var ds = new DataSet DataSetName = "ValidatorsByTask";
ds.Tables.Add(dsTasks.Tables[0].Copy());
ds.Tables.Add(dsValidators.Tables[0].Copy());
ds.Tables.Add(dsProperties.Tables[0].Copy());
ds.Relations.Add("Task_Validators", ds.Tables["Tasks"].Columns["Id"], ds.Tables["Validators"].Columns["TaskId"]);
ds.Relations.Add("Validator_Properties", ds.Tables["Validators"].Columns["Id"], ds.Tables["ValidatorProperties"].Columns["ValidatorId"]);
var data = ConvertDataSetWithRelationsToCamelCaseObject(ds);
【讨论】:
【参考方案4】:在 CamelCase 与默认的 .NET 的 PascalCase 中格式化 JSON 输出的简短且非常简单的解决方案。
将以下两行添加到您的 WebApiConfig.cs 文件(在 WebApi 2 的 App_Start 文件夹下):
// Get the default json formatter
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
// Switch from PascalCase to CamelCase
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
【讨论】:
以上是关于CamelCase JSON WebAPI 子对象(嵌套对象、子对象)的主要内容,如果未能解决你的问题,请参考以下文章
在每个控制器的 ASP.NET WebAPI 上强制使用 CamelCase
Flutter 和 Net Core WebApi 之间的 Json 案例解析问题
将返回的 JSON 对象属性转换为(较低的第一个)camelCase