2017-09-12 3 views
0

J'essaie d'utiliser le Highrise Api avec le .NET 4.5 wrapper by scottschluer afin de poster une nouvelle personne sur notre compte Highrise avec les données personnalisées qu'ils saisissent.Highrise Api, Données du sujet ne pas poster avec RestSharp

Le problème que je rencontre est avec les données personnalisées. L'objet personne est correctement affiché, mais les champs de données du sujet ne sont pas inclus dans le message. J'ai rencontré cet article: Highrise Custom Fields. Il semblait que la chose qui manquait était l'attribut type="array" du champ subject_datas. J'ai testé cette hypothèse en créant manuellement une requête en utilisant la valeur sérialisée de l'objet que j'essayais de publier. Le résultat de ce test a été une publication réussie sur le serveur avec tous les champs de données personnalisés remplis.

J'ai essayé d'étendre les classes à partir de l'assembly wrapper pour ajouter cet attribut manquant à la liste, mais cela ne semblait toujours pas fonctionner. L'objet Person a une propriété pour une liste d'objets SubjectData, j'ai écrasé cette propriété dans une classe enfant pour utiliser une classe personnalisée à la place. De cette façon, je pourrais ajouter une propriété à utiliser comme attribut. Cette classe personnalisée ne semblait toujours pas fonctionner.

Après avoir regardé le code pour RestSharp's XmlSerializer, il semble qu'il ajoutera seulement une liste d'éléments quand cet objet implémente IList. Ce n'était pas un problème, j'ai pu le faire fonctionner, mais le code ne semble pas permettre d'ajouter des attributs à l'élément list. Il ne regarde que les enfants de la classe list et ignore les autres propriétés de l'objet.

Alors ma question est la suivante:

Est-il possible d'appliquer des attributs à une propriété de liste dans RestSharp, ou est-il une autre façon d'ajouter l'attribut type="array" au nœud data_subjects XML avant la demande est envoyée?

Répondre

1

J'ai finalement résolu le problème moi-même en créant une nouvelle classe de requête qui créerait une RestRequest en utilisant un XmlSerializer personnalisé.

Je puis étendu la classe personne et cachèrent la propriété derrière une propriété objet liste personnalisée

Avant:

[SerializeAs(Name = "subject_datas")] 
public List<SubjectData> SubjectDatas { get; set; } 

Après:

[SerializeAs(Name = "subject_datas")] 
public new SubjectDataList SubjectDatas { get; set; } 

La classe SubjectDataList est juste un emballage pour List<SubjectData>.

SubjectDataList implémente une interface appelée ISerializeList<SubjectData> qui est défini comme:

interface ISerializeList : IEnumerable {} 
interface ISerializeList<T> :IEnumerable<T>, ISerializeList {} 

SubjectDataList a également une propriété de type à rendre l'attribut type sur le nœud subjectdatas de la demande de repos.

[SerializeAs(Name = "type", Attribute = true)] 
public string Type { get; set; } = "array"; 

Je me suis alors fait une classe appelée qui implémente ISerializer. J'ai copié l'implémentation de XmlSerializer, mais j'ai apporté quelques modifications.Dans la méthode Map, il y a une partie qui vérifie si la variable rawValue est . J'ai légèrement modifié cette partie et ajouté une clause pour ma classe .

Il ressemble maintenant à ceci:

if (propType.IsPrimitive || propType.IsValueType || propType == typeof(string)) { 
    //... 
} else if (rawValue is IList) { 
    ProcessIList((IList) rawValue, element); 
} else if (rawValue is ISerializeList) { 
    ProcessISerializeList((ISerializeList) rawValue, element); 
} else { 
    Map(element, rawValue); 
} 

ProcessIList et ProcessISerializeList sont définis comme:

private void ProcessIList(IList list, XElement element) { 
    ProcessIEnumerable(list, element); 
} 
private void ProcessISerializeList(ISerializeList list, XElement element) { 
    ProcessIEnumerable(list, element); 
    Map(element, list); 
} 
private void ProcessIEnumerable(IEnumerable list, XElement element) { 
    var itemTypeName = ""; 
    foreach (var item in list) { 
     if (itemTypeName == "") { 
      var type = item.GetType(); 
      var setting = type.GetAttribute<SerializeAsAttribute>(); 

      itemTypeName = setting != null && setting.Name.HasValue() ? setting.Name : type.Name; 
     } 

     var instance = new XElement(itemTypeName.AsNamespaced(Namespace)); 

     Map(instance, item); 
     element.Add(instance); 
    } 
} 

J'espère que cette réponse sera en mesure d'aider toute autre personne ayant des problèmes avec ce problème.