2014-02-07 10 views
11

Ich verwende RestSharp (Version 104.4 über NuGet), um Aufrufe an einen Rest-Webdienst zu senden. Ich habe eine Reihe von Objekten (POCO) entworfen, die mit Ressourcen in der API übereinstimmen. Die Objekteigenschaftsnamen meiner Objekte stimmen jedoch nicht mit denen überein, die vom Restdienst beim Posten von Daten erwartet werden. Daher möchte ich sie "transformieren", wenn ich eine Anfrage an den Rest-Dienst mache, damit sie mit der Übereinstimmung übereinstimmen. Ich habe gelesen, dass das Hinzufügen von SerializeAs Attribut (mit einem Namen angegeben) auf meiner POCO-Eigenschaft wird sie korrekt serialisieren, aber es wird nicht.RestSharp-Serialisierung zu JSON, Objekt verwendet SerializeAs-Attribut nicht wie erwartet

Mein POCO

Imports RestSharp.Serializers 

<Serializable(), SerializeAs(Name:="ApiMember")> 
Public Class ApiMember 
    <SerializeAs(Name:="id")> 
    Public Property Id As Integer? 

    <SerializeAs(Name:="email")> 
    Public Property EmailAddress As String 

    <SerializeAs(Name:="firstname")> 
    Public Property Firstname As String 

    <SerializeAs(Name:="lastname")> 
    Public Property Lastname As String 
End Class 

Mein Aufruf an die API

Dim request As RestRequest = New RestRequest(Method.POST) 
Dim member As ApiMember = new ApiMember() 

member.EmailAddress = "[email protected]" 

request.Resource = "members" 
request.RequestFormat = DataFormat.Json 
request.AddBody(member) 

Dim client As RestClient = New RestClient() 
client.BaseUrl = "http://url.com" 
client.Authenticator = New HttpBasicAuthenticator("username", "password") 
client.Execute(Of ApiGenericResponse)(request) 

Was geschrieben endet als

{"Id":null,"EmailAddress":"[email protected]","Firstname":null,"Lastname":null} 

Nein tice der Name der Eigenschaften stimmt nicht mit denen ich in SerializeAs angegeben (Großbuchstaben, Name der EmailAddress)

Fehle ich etwas?

+0

Ich bin über das gleiche Problem gestolpert - wie hast du das gelöst? –

+0

Wenn Sie glauben, dass eine dieser Antworten Ihnen geholfen hat, Ihr Problem zu lösen, dann bitte [** akzeptiere diese Antwort **] (http://meta.stackoverflow.com/q/5234/153998). Dies wird Ihre Wertschätzung für die Menschen zeigen, die Ihre Zeit damit verbracht haben, Ihnen zu helfen *. –

+0

@marc_s Ich habe es nicht gelöst, ich habe zu dieser Zeit mit RestSharp experimentiert, und ich habe entweder diese "umbenannten" Eigenschaften nicht verwendet oder meine POCO-Eigenschaften umbenannt, um sie mit denen der REST-API zu vergleichen. – MaxiWheat

Antwort

17

Dies ist für @MaxiWheat und alle anderen, die daran interessiert sind, JSON.NET als JSON-Serializer in einer RestSharp-Anfrage zu verwenden. Grundsätzlich habe ich den Ansatz beschrieben in this blog post by Patrick Riley:

// create the request 
var request = new RestRequest(yourUrlHere, Method.POST) { RequestFormat = DataFormat.Json }; 

// attach the JSON.NET serializer for RestSharp 
restRequest.JsonSerializer = new RestSharpJsonNetSerializer(); 

und die RestSharpJsonNetSerializer ist eine Implementierung (weniger als 100 Zeilen Code) von den JSON.NET Jungs (John Sheehan), dass can be found on their Github pages

Mit diesem Setup , meine Probleme gingen weg und ich konnte ein korrektes DTO mit netten CamelCase-Eigenschaften haben, während das serialisierte JSON sie in allen "Kleinbuchstaben" verwendet.

+0

Aber es funktioniert nicht zum Deserialisieren. Wie kann ich ein solches Verhalten mit Antwortdaten erhalten? – Neshta

+0

@Neschta - Vermutlich haben Sie die Antwort gefunden, aber wenn nicht, können Sie den Standard-IDeserializer mit RestClient.AddHandler mit Ihrer eigenen Implementierung überschreiben (ähnlich der Antwort von marc_s.) Dieser Blog enthält eine Beispielimplementierung eines ISerializer und IDeserializer für Newtonsoft.JSON: http://bytefish.de/blog/restharp_custom_json_serializer/ –

7

In RestSharp 104.4 verwendet der Standardwert JsonSerializer nicht das Attribut [SerializeAs], wie aus der Überprüfung der source code ersichtlich ist.

Eine Abhilfe hierfür ist ein benutzerdefinierten Serializer zu erstellen, die die Json.NET verwendet JsonSerializer (ein gutes Beispiel ist here) und dann Eigenschaften mit dem [JsonProperty] Attribute schmückt, etwa so:

<JsonProperty("email")> 
Public Property EmailAddress As String 
6

RestSharp Anwendungen SimpleJson. Diese Bibliothek kennt oder respektiert das [SerializeAs] Attribut (is XML-only anyway) nicht, es ist nur outputs the POCO's property name, es sei denn, es ist mit #SIMPLE_JSON_DATACONTRACT definiert, dann können Sie das Attribut [DataContract] verwenden, um Eigenschaften umzubenennen.

Ihre Optionen scheinen also zu sein, die SimpleJson-Bibliothek mit dem Attribut [DataContract(Name="lowercasepropertyname")] neu zu definieren und zu dekorieren oder einen benutzerdefinierten Serializer zu erstellen, der einen JSON-Serializer verwendet, der andere Attribute berücksichtigt, wie in @ Ryan's Antwort vorgeschlagen.

+1

Dank ein Heap - endete JSON.NET wieder in RestSharp und jetzt funktioniert es. Warum wurde JSON.NET als Abhängigkeit entfernt, wenn der "Ersatz" so kaputt ist, dass jeder JSON.NET trotzdem wieder in RestSharp einbinden muss!?!?!? ..... –

+0

Ich weiß nicht, ich denke, eine REST-Bibliothek könnte sowieso sehr von einer vollwertigen JSON-Bibliothek profitieren ... – CodeCaster

+0

@marc_s Kannst du posten, wie du JSON.NET wieder in RestSharp gesteckt hast? Ich denke, es hätte mir geholfen, wenn ich daran herumgebastelt hätte. Es erschien mir ein wenig kompliziert, ich bin noch nicht so erfahren in .NET. – MaxiWheat

2

Ich bin auf dieses Problem gestoßen, und löste das etwas anders als oben, wollte es hier notieren.

Wir haben eine factory Klasse, die alle unsere Anfragen erstellt. Sieht aus wie die folgende

public IRestRequest CreatePutRequest<TBody>(string resource, TBody body) 
{ 
    var request = new RestRequest(resource) 
    { 
     Method = Method.PUT, 
    }; 

    request.AddParameter("application/json", Serialize(body), ParameterType.RequestBody); 
    return request; 
} 

als vielmehr nutzen die AddJsonBody und AddBody Methoden gegen den Antrag, die beide die Serialisierung verursachen, benutzte ich AddParameter, die das Objekt hinzufügen, werden Sie in ohne Serialisierung passieren. Ich habe eine Methode namens Serialise erstellt, die JSON.net verwendet, um unsere Klasse zu serialisieren. Diese

private object Serialize<T>(T item) 
{ 
    return JsonConvert.SerializeObject(item); 
} 

dann können wir JSON.net ‚s JsonProperty Anmerkung über Ihre propertys verwenden. Hier ist ein Beispiel -

public class Example 
{ 

    [JsonProperty(PropertyName = "name")] 
    public string Name { get; set; } 

    [JsonProperty(PropertyName = "created")] 
    public DateTime Created { get; set; } 

    [JsonProperty(PropertyName = "updated")] 
    public DateTime Updated { get; set; } 

}