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请求和响应。
对
更新
既然你把服务合同也牵扯进来了,我明白还有一个更根本的问题。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等