RestSharp序列化为JSON,对象未按预期使用SerializeAs属性

Max*_*eat 13 .net vb.net rest json restsharp

我正在使用RestSharp(通过NuGet版本104.4)来调用Rest Web服务.我设计了一组对象(PO​​CO),它匹配API中公开的资源.但是,我的对象属性名称与发布数据时Rest服务所期望的属性名称不匹配,所以当我向Rest服务发出请求以使它们匹配匹配时,我想"转换"它们.我读到SerializeAs在我的POCO属性上添加属性(指定了Name)将使它们正确序列化,但它不会.

我的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
Run Code Online (Sandbox Code Playgroud)

我对API的呼唤

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

member.EmailAddress = "me@example.com"

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)
Run Code Online (Sandbox Code Playgroud)

什么最终被张贴

{"Id":null,"EmailAddress":"me@example.com","Firstname":null,"Lastname":null}
Run Code Online (Sandbox Code Playgroud)

请注意,属性的名称与我在SerializeAs(大写,EmailAddress的名称)中指定的名称不匹配

我错过了什么吗?

mar*_*c_s 24

这适用于@MaxiWheat和其他任何对如何在RestSharp请求中使用JSON.NET作为JSON序列化程序感兴趣的人.基本上,我使用了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();
Run Code Online (Sandbox Code Playgroud)

RestSharpJsonNetSerializer是JSON.NET人员(John Sheehan)的一个实现(少于100行代码),可以在他们的Github页面上找到

通过这种设置,我的问题消失了,我能够拥有一个具有良好CamelCase属性的正确DTO,而序列化JSON使用所有"小写".

  • 注意:Patrick 的博客文章将类称为“RestSharpJsonNetSerializer”,而存储库中文件的链接的类名为“JsonSerializer”。如果您在不注意的情况下复制和粘贴,那将是一个小小的减速。问我怎么知道... (2认同)

Nat*_*han 9

我遇到了这个问题,并以与上面略有不同的方式解决了这个问题,想在这里注意一下。

我们有一个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;
}
Run Code Online (Sandbox Code Playgroud)

我不是针对请求使用AddJsonBodyand AddBody方法,这两者都会导致序列化,而是使用AddParameter了它将添加您传入的对象而无需序列化的方法。我创建了一个名为的方法Serialise,该方法JSON.net用于序列化我们的类。

private object Serialize<T>(T item)
{
    return JsonConvert.SerializeObject(item);
}
Run Code Online (Sandbox Code Playgroud)

然后,我们可以在您的媒体资源上方使用JSON.netJsonProperty注释。这是一个例子-

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

}
Run Code Online (Sandbox Code Playgroud)


Rya*_*ohn 6

在RestSharp 104.4中,默认情况下JsonSerializer不使用该[SerializeAs]属性,如查看源代码所示.

一个解决方法是创建一个使用Json.NET的自定义序列化程序JsonSerializer(这里有一个很好的例子),然后用[JsonProperty]属性装饰你的属性,如下所示:

<JsonProperty("email")>
Public Property EmailAddress As String
Run Code Online (Sandbox Code Playgroud)

  • 这就是为什么仅链接(或多数为链接)答案不好的原因。这两个链接均已失效,并且没有有关如何创建自定义序列化程序的信息。 (3认同)

Cod*_*ter 6

RestSharp使用SimpleJson.这个库不知道或不尊重该[SerializeAs]属性(无论如何都是XML),它只输出POCO的属性名,除非用已#SIMPLE_JSON_DATACONTRACT定义的编译,然后你可以使用该[DataContract]属性重命名属性.

因此,您的选择似乎是使用该[DataContract(Name="lowercasepropertyname")]属性重新编译SimpleJson库并使用该属性修饰您的属性,或创建一个使用JSON序列化程序的自定义序列化程序,该序列化程序遵循@ Ryan的答案中建议的其他属性.

  • 感谢一堆 - 最终将JSON.NET插回到RestSharp中,现在它可以工作了.为什么JSON.NET作为依赖项被删除,如果"替换"如此破碎,以至于每个人都需要将JSON.NET重新插入RestSharp!?!?!?..... (2认同)