2014-02-07 16 views
11

我正在使用RestSharp(通過NuGet 104.4版)調用Rest Web Service。我設計了一組匹配API中暴露資源的對象(PO​​CO)。但是,我的對象屬性名稱與發佈數據時Rest服務所期望的屬性名稱不匹配,所以我想在向Rest服務發出請求以使它們匹配匹配時對其進行「轉換」。我讀到在我的POCO屬性中添加SerializeAs屬性(使用指定的名稱)會使它們正確序列化,但它不會。RestSharp序列化爲JSON,對象未按預期使用SerializeAs屬性

我的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 

我打電話給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) 

什麼最終被張貼

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

無tice這些屬性的名稱與我在SerializeAs(大寫字母,電子郵件地址的名稱)中指定的大小寫不一致

我錯過了什麼嗎?

+0

我絆倒了同樣的問題 - 你是如何解決這個問題的? –

+0

如果您覺得其中某個答案有助於您解決問題,請[**接受此答案**](http://meta.stackoverflow.com/q/5234/153998)。這將表明你對那些花時間幫助你的人表示感謝。 –

+0

@marc_s我沒有真正解決它,當時我正在嘗試使用RestSharp,結果我沒有使用那些「重命名」屬性,或者只是重命名我的POCO屬性以匹配REST API的屬性。 – MaxiWheat

回答

17

這是針對@MaxiWheat和其他任何對如何在RestSharp請求中使用JSON.NET作爲JSON序列化程序感興趣的人。基本上,我使用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(); 

RestSharpJsonNetSerializer是一個實現從JSON.NET人(約翰希恩),該(小於100行代碼)can be found on their Github pages

採用這種設置,我的問題消失了,我能夠擁有一個具有很好的CamelCase屬性的正確的DTO,而序列化的JSON以全部「小寫」使用它們。

+0

但它不適用於反序列化。我如何獲得響應數據的這種行爲? – Neshta

+0

@Neshta - 現在猜測你找到了答案,但是如果沒有,你可以使用RestClient.AddHandler來重寫默認的IDeserializer和你自己的實現(類似於marc_s的答案)。這個博客有一個ISerializer和IDeserializer的樣本實現, Newtonsoft.JSON:http://bytefish.de/blog/restsharp_custom_json_serializer/ –

7

在RestSharp 104.4中,默認JsonSerializer不使用[SerializeAs]屬性,如查看source code所示。

一個變通方法是創建一個使用Json.NET JsonSerializer自定義序列(一個很好的例子是here),然後用[JsonProperty]屬性裝飾你的屬性,像這樣:

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

RestSharp用途SimpleJson。這個庫不知道或不尊重[SerializeAs]屬性(它is XML-only anyway),它只是outputs the POCO's property name,除非它編譯了#SIMPLE_JSON_DATACONTRACT定義,那麼你可以使用[DataContract]屬性來重命名屬性。

所以你的選擇似乎是重新編譯SimpleJson庫定義,並與[DataContract(Name="lowercasepropertyname")]屬性裝飾你的屬性,或創建一個使用JSON序列,做尊重其他屬性自定義序列建議在@瑞安的答案。

+1

感謝一堆 - 最終將JSON.NET插入到RestSharp中,現在它可以工作。爲什麼JSON.NET作爲一個依賴項被刪除,如果「替換」被破壞了,每個人都需要將JSON.NET插回到RestSharp中呢!!!?!? ..... –

+0

我不知道,我認爲一個REST庫可以很好地從一個完整的JSON庫中受益......無論如何 – CodeCaster

+0

@marc_s你可以發佈如何將JSON.NET插回到RestSharp嗎?我認爲這會幫助我,當我修補它。這對我來說似乎有點複雜,我在.NET方面還沒有那麼多的經驗。 – MaxiWheat

2

我遇到了這個問題,並解決了這個與上面略有不同的方式,想在這裏注意它。

我們有一個factory類,它構建了我們所有的請求。如下所示

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

而不是使用AddJsonBodyAddBody方法對抗的要求,這兩者導致系列化,我用AddParameter這將增加你在沒有經過序列化的對象。我創建了一個名爲Serialise的方法,它使用JSON.net來序列化我們的類。

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

這就允許我們使用JSON.netJsonProperty註釋以上的propertys。這裏是一個例子 -

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

} 
相關問題