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

xuo3flqw  于 2022-12-24  发布在  .NET
关注(0)|答案(5)|浏览(243)

我正在使用RestSharp(版本104.4,通过NuGet)调用Rest Web服务。(POCO),它与API中公开的资源匹配。但是,我的对象属性名称与Rest服务在发布数据时所需的名称不匹配,因此,当我向Rest服务发出请求以使它们匹配时,我希望“转换”它们。(指定了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

我对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)

最后什么被张贴

{"Id":null,"EmailAddress":"me@example.com","Firstname":null,"Lastname":null}

请注意,属性的名称与我在SerializeAs中指定的名称(大写,EmailAddress的名称)不匹配
我错过什么了吗?

slwdgvem

slwdgvem1#

这是为@MaxiWheat和其他对如何在RestSharp请求中使用JSON.NET作为JSON序列化器感兴趣的人准备的。

// 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开发人员(JohnSheehan)的一个实现(不到100行代码),
有了这个设置,我的问题就消失了,而且我能够拥有一个具有良好CamelCase属性的适当DTO,而序列化JSON使用的都是“小写”。

c8ib6hqw

c8ib6hqw2#

我遇到了这个问题,解决这个问题的方式略有不同,比上面,想在这里注意到它。
我们有一个构建所有请求的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注解。

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

}
n6lpvg4x

n6lpvg4x3#

RestSharp使用SimpleJson。这个库不知道也不尊重[SerializeAs]属性(哪个is XML-only anyway),它只输出POCO的属性名,除非它是用定义的#SIMPLE_JSON_DATACONTRACT编译的,那么你可以使用[DataContract]属性来重命名属性。
因此,您的选择似乎是使用[DataContract(Name="lowercasepropertyname")]属性来定义和修饰您的属性,或者创建一个自定义序列化器,该序列化器使用一个JSON序列化器,该序列化器不考虑@Ryan答案中建议的其他属性。

yrwegjxp

yrwegjxp4#

在RestSharp 104.4中,默认的JsonSerializer不使用[SerializeAs]属性,这可以通过查看source code看到(注意,如问题中所示,此代码来自v104.4,而不是最新版本)。
一种解决方法是创建一个使用Json.NET JsonSerializerhere是一个很好的示例)的自定义序列化程序,然后使用[JsonProperty]属性修饰属性,如下所示:

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

vkc1a9a25#

您可以在客户端使用以下方法。它实际上是使用Newtonsoft反序列化程序而不是内置的RestSharp反序列化程序。Newtonsoft反序列化程序遵循DataMember Name属性或JsonProperty。

private T Execute<T>(RestRequest request)
    {
        var response = _client.Execute(request);
        if (response.ErrorException != null)
            throw new Exception("Error:" + response.ErrorException);

        return (T)JsonConvert.DeserializeObject(response.Content, typeof(T));
    }

相关问题