Json的属性映射问题.Net和WCF数据成员

本文关键字:WCF 数据成员 Net 问题 属性 映射 Json | 更新日期: 2023-09-27 18:01:27

我使用Json。Net Nuget包将Json对象反序列化为c#具体对象。我的Json对象有snake_套管键"property_name",但我的c#对象是以下camel套管"propertyName"。当我反序列化对象时,它工作得很好,但当我试图从WCF服务反序列化相同的Json对象时,它没有映射到c#类的属性。

var eventMessage = JsonConvert.DeserializeObject<TestClass>( JsonMessage );

ServiceContract:

 [ServiceContract]
public interface IService
{
    [OperationContract]
    [FaultContract( typeof( MessageUnAuthenticatedFault ))]
    [WebInvoke( Method = "POST",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json,
        UriTemplate = "Process" )]
    string Process( string message );
}

这是我的数据合同

[DataContract]
public class TestClass
{
    [DataMember]
    public long Id { get; set; }
    [DataMember]
    [JsonProperty( PropertyName = "request_name" )]
    public string RequestedName { get; set; }
    [DataMember]
    [JsonProperty( PropertyName = "request_type" )]
    public string RequestType { get; set; }
    [DataMember]
    [JsonProperty( PropertyName = "request_key" )]
    public string RequestKey { get; set; }
    [DataMember]
    [JsonProperty( PropertyName = "descriptive_name" )]
    public string DescriptiveName { get; set; } = null;
    [DataMember]
    [JsonProperty( PropertyName = "owner_internal_id" )]
    public string OwnerInternalId { get; set; }
    [DataMember]
    public string URL { get; set; }
    [DataMember]
    public Status Status { get; set; }
    [DataMember]
    public DateTime? Created { get; set; }
    [DataMember]
    public DateTime? Modified { get; set; }
}

Json对象是这样的:

{"generated": "2016-08-04T08:06+0000", "request_type": "test", "request_key": "1111", "descriptive_name": "Description", "owner_internal_id": "1213456", "Created":"2016-08-04T08:00"}

为什么Json。在WCF服务的情况下,Net没有正确映射属性?

p。S:我的服务只支持JSON请求和响应。

Json的属性映射问题.Net和WCF数据成员

更新

既然你把服务合同也牵扯进来了,我明白还有一个更根本的问题。WCF用于交换数据契约对象,并且与XML和JSON之间的格式无关。它是如此的不可知,以至于没有直接的方法来访问底层的原始请求或响应流。相反,WCF坚持为您做绑定。由于您上传的JSON不是JSON原语,因此尝试将其绑定到string message失败。相反,您需要按照 的行定义您的服务。
[ServiceContract]
public interface IService
{
    [OperationContract]
    [FaultContract( typeof( MessageUnAuthenticatedFault ))]
    [WebInvoke( Method = "POST",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json,
        UriTemplate = "Process" )]
    ResponseClass Process( TestClass message );
}

其中ResponseClass是您想返回的任何值。看一下WCF rest服务获取post JSON数据和使用DataContract检索JSON数据的例子。

如果您确实需要底层post流来进行手动解析,您可以尝试WCF REST服务JSON post数据和WCF + REST中的技术:请求数据在哪里?

原始回答

WCF不使用Json。. NET用于JSON序列化。它使用DataContractJsonSerializer。因此,用[JsonProperty]注释类型将没有效果。相反,您需要设置DataMemberAttribute.Name,即:

[DataContract]
public class TestClass
{
    [DataMember]
    public long Id { get; set; }
    [DataMember(Name = "request_name")]
    public string RequestedName { get; set; }
    [DataMember(Name = "request_type")]
    public string RequestType { get; set; }
    [DataMember(Name = "request_key")]
    public string RequestKey { get; set; }
    [DataMember(Name = "descriptive_name")]
    public string DescriptiveName { get; set; }
    [DataMember(Name = "owner_internal_id")]
    public string OwnerInternalId { get; set; }
    [DataMember]
    public string URL { get; set; }
    [DataMember]
    public Status Status { get; set; }
    [DataMember]
    public DateTime? Created { get; set; }
    [DataMember]
    public DateTime? Modified { get; set; }
}

要使用此序列化器测试独立JSON反序列化,您可以使用以下帮助器方法:

public static partial class DataContractJsonSerializerHelper
{
    private static MemoryStream GenerateStreamFromString(string value)
    {
        return new MemoryStream(Encoding.Unicode.GetBytes(value ?? ""));
    }
    public static string SerializeJson<T>(T obj, DataContractJsonSerializer serializer = null)
    {
        serializer = serializer ?? new DataContractJsonSerializer(obj.GetType());
        using (var memory = new MemoryStream())
        {
            serializer.WriteObject(memory, obj);
            memory.Seek(0, SeekOrigin.Begin);
            using (var reader = new StreamReader(memory))
            {
                return reader.ReadToEnd();
            }
        }
    }
    public static T DeserializeJson<T>(string json, DataContractJsonSerializer serializer = null)
    {
        serializer = serializer ?? new DataContractJsonSerializer(typeof(T));
        using (var stream = GenerateStreamFromString(json))
        {
            var obj = serializer.ReadObject(stream);
            return (T)obj;
        }
    }
}

然后做:

var test = DataContractJsonSerializerHelper.DeserializeJson<TestClass>(jsonString);

您还必须以Microsoft首选的"/Date(1329159196126-0500)/"格式格式化DateTime属性,或者使用反序列化代理来进行手动解析。参见DataContractJsonSerializer -在列表中反序列化DateTime和WCF可扩展性-序列化代理了解详细信息。内JSON日期和时间字符串的背景。或者为每个DateTime使用代理属性,例如:

    [IgnoreDataMember]
    public DateTime? Created { get; set; }
    [DataMember(Name = "Created")]
    string CreatedString
    {
        get
        {
            if (Created == null)
                return null;
            // From https://stackoverflow.com/questions/114983/given-a-datetime-object-how-do-i-get-a-iso-8601-date-in-string-format
            return Created.Value.ToString("s", System.Globalization.CultureInfo.InvariantCulture);
        }
        set
        {
            if (string.IsNullOrEmpty(value))
                Created = null;
            else
                Created = DateTime.Parse(value);
        }
    }
    [DataMember]
    public DateTime? Modified { get; set; }
}

如果你真的想使用Json。NET使用WCF进行反序列化,您将需要做一些工作。参见c# WCF REST -如何使用JSON。. Net序列化器而不是默认的DataContractSerializer?并且,可能的话,使用自定义WCF正文反序列化而不更改URI模板反序列化。

有关各种Microsoft框架使用的JSON序列化器的概要,请参阅ASP中的JSON序列化器。. NET等