CamelCase sous-objets WebAPI JSON (objets imbriqués, objets enfant) )

je crée un objet complexe avec des enfants (objets imbriqués) à retourner à partir de mon contrôleur d'api web. L'objet contient la liste des autres types d'objet. Ces types de sous-objets dans la liste suivent le boîtier pascal utilisé .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 };

mon problème est que WebAPI ne camel case chacune des propriétés des sous-Articles. Par exemple, la première personne dans la liste des personnes devrait avoir et les attributs de id, name à la place du cas pascal. Id, Nom. Il en va de même pour tous les autres sous-postes.

2
demandé sur Andre Young 2014-04-29 20:47:20

4 réponses

vous pouvez configurer JSON.NET pour produire des noms de cas de chameau dans votre démarrage d'application. Code extrait de Post de Scott Allen :

var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
7
répondu Ufuk Hacıoğulları 2014-11-19 15:43:14

j'ai eu le même problème. Je retourne un objet pour la population de la grille. Il a des propriétés comme Rows, Page, Total etc. Le réglage du résolveur de contrat à camel case résout le problème pour les propriétés au niveau supérieur. Mais si une propriété contient une liste d'objets avec des noms de propriétés casés pascal, cela ne change pas leur cas.

voici Donc ce que j'ai fait pour contourner le problème.

objet Grille de données avec des données de retour

[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; }
}

ici Rows contient la liste des objets. Ici je retournais la liste des objets modèles. La classe du modèle ressemble à:

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()
    {}
}

et voici comment j'ai retourné les données JSON de mon contrôleur D'API

    [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 ="")] indique quel nom utiliser pour la propriété lorsque l'objet est sérialisé.

Espérons que cette aide!

1
répondu Mayank Sharma 2014-12-18 08:08:15

j'ai eu un problème similaire avec les objets imbriqués en essayant de retourner un ensemble de données avec des relations de WebAPI. Utiliser un ExpandoObject a fait l'affaire pour moi, peut-être que cela vous aidera.

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);
        }

exemple de code pour créer un ensemble de données avec des relations:

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);
0
répondu barsh 2014-08-15 16:21:59

une solution courte et très simple pour formater la sortie JSON dans CamelCase versus la PascalCase de .NET par défaut.

ajouter à votre WebApiConfig.fichier cs (sous le dossier App_Start à WebApi 2) les deux lignes suivantes:

// Get the default json formatter 
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();

// Switch from PascalCase to CamelCase
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
-1
répondu Segev -CJ- Shmueli 2015-03-18 04:37:29