C# WCF JSON序列化不一致,因此如何正确地反序列化它?

C# WCF JSON序列化不一致,因此如何正确地反序列化它?,c#,json,wcf,serialization,C#,Json,Wcf,Serialization,我有一个可序列化的多态类型和一个服务契约 [DataContract] [KnownType(typeof(SomethingA))] [KnownType(typeof(SomethingB))] 公开课 { [数据成员] 公共int Item1{get;set;} [数据成员] 公共字符串Item2{get;set;} } [数据合同] A:什么 { } [数据合同] B:什么 { } [服务合同] [ServiceKnownType(typeof(SomethingA))] [Servic

我有一个可序列化的多态类型和一个服务契约

[DataContract]
[KnownType(typeof(SomethingA))]
[KnownType(typeof(SomethingB))]
公开课
{
[数据成员]
公共int Item1{get;set;}
[数据成员]
公共字符串Item2{get;set;}
}
[数据合同]
A:什么
{ }
[数据合同]
B:什么
{ }
[服务合同]
[ServiceKnownType(typeof(SomethingA))]
[ServiceKnownType(类型(SomethingB))]
公共接口测试
{
[经营合同]
[WebInvoke(
RequestFormat=WebMessageFormat.Json,
ResponseFormat=WebMessageFormat.Json,
BodyStyle=WebMessageBodyStyle.Bare,
UriTemplate=“使用某物”,
Method=“POST”)]
某物;某物;
[经营合同]
[WebInvoke(
RequestFormat=WebMessageFormat.Json,
ResponseFormat=WebMessageFormat.Json,
BodyStyle=WebMessageBodyStyle.Bare,
UriTemplate=“使用多态某物”,
Method=“POST”)]
列出UsePolymorphicSomethings();
[经营合同]
[WebInvoke(
RequestFormat=WebMessageFormat.Json,
ResponseFormat=WebMessageFormat.Json,
BodyStyle=WebMessageBodyStyle.Bare,
UriTemplate=“抛出web异常”,
Method=“POST”)]
void ThrowServerException();
}
…以及该合同的实施

使用System.Net;
使用System.ServiceModel.Web;
公共类测试:ITesting
{
公共某物使用某物
{
SomethingA a=新的SomethingA();
a、 项目1=2;
a、 项目2=“b”;
返回a;
}
公共列表UsePolymorphicSomethings()
{
List retVal=新列表();
Add(newsomethinga{Item1=1,Item2=“1”});
Add(newsomethingb{Item1=1,Item2=“1”});
返回返回;
}
public void ThrowServerException()
{
尝试
{
抛出新的应用程序异常(“坏消息”);
}
捕获(ApplicationException e)
{
抛出新的WebFaultException(e,HttpStatusCode.InternalServerError);
}
}
}
我在另一个组件中进行了一些功能测试

使用System.Net;
使用System.Net.Http;
使用System.Runtime.Serialization.Json;
[测试方法]
public void useu\u WebTest()
{
使用(HttpClient http=newhttpclient())
{
http.BaseAddress=TestUtil.TestsBaseAddress;
HttpResponseMessage response=http.PostAsJsonAsync(“使用某物”,
新的StringContent(string.Empty)).Result;
字符串ret1=response.Content.ReadAsStringAsync().Result;
//将某物反序列化为某物。
Stream=response.Content.ReadAsStreamAsync().Result;
DataContractJsonSerializer serializer=新的DataContractJsonSerializer(typeof(Something));
Something ret=(Something)serializer.ReadObject(stream);
//失败了。
AreEqual(typeof(SomethingA),ret.GetType());
}
}
[测试方法]
public void UsePolymorphicSomethings_WebTest()
{
使用(HttpClient http=newhttpclient())
{
http.BaseAddress=TestUtil.TestsBaseAddress;
HttpResponseMessage response=http.PostAsJsonAsync(“使用多态的东西”,
新的StringContent(string.Empty)).Result;
字符串ret2=response.Content.ReadAsStringAsync().Result;
//正确地反序列化A和B。
Stream=response.Content.ReadAsStreamAsync().Result;
DataContractJsonSerializer serializer=新的DataContractJsonSerializer(typeof(List));
List somethings=(List)serializer.ReadObject(stream);
//成功。
AreEqual(typeof(SomethingA),something[0].GetType());
AreEqual(typeof(SomethingB),somethings[1].GetType());
}
}
[测试方法]
public void ThrowServerException1_WebTest()
{
使用(HttpClient http=newhttpclient())
{
http.BaseAddress=TestUtil.TestsBaseAddress;
HttpResponseMessage response=http.PostAsync(“抛出web异常”,
新的StringContent(string.Empty)).Result;
AreEqual(HttpStatusCode.InternalServerError,response.StatusCode);
字符串ret3=response.Content.ReadAsStringAsync().Result;
//将ApplicationException反序列化为异常。
Stream=response.Content.ReadAsStreamAsync().Result;
DataContractJsonSerializer serializer=新的DataContractJsonSerializer(typeof(Exception));
异常e=(异常)序列化程序.ReadObject(流);
//失败了。
AreEqual(typeof(ApplicationException),e.GetType());
}
}
正在使用的Web测试ret1是:

"{\"Item1\":2,\"Item2\":\"b\"}"
…由于没有嵌入类型信息,因此DataContractJsonSerializer无法反序列化返回的对象的正确类型,这并不奇怪

正在使用的多态性内容\u WebTest ret2是:

"[{\"__type\":\"SomethingA:#InSite8WebServiceLib\",\"Item1\":1,\"Item2\":\"1\"},{\"__type\":\"SomethingB:#InSite8WebServiceLib\",\"Item1\":1,\"Item2\":\"1\"}]"
…类型信息以_类型条目的形式嵌入,DataContractJsonSerializer会正确反序列化这些条目

在ThrowServerException1\u WebTest ret3中:

"{\"ClassName\":\"System.ApplicationException\",\"Message\":\"Bad news.\",\"Data\":null,\"InnerException\":null,\"HelpURL\":null,\"StackTraceString\":\"   at InSite8WebServiceLib.Testing.ThrowServerException() in d:\\\\SvnSource\\\\Hammersmith\\\\trunk\\\\VisualStudioProjects\\\\InSite8WebService\\\\InSite8WebServiceLib\\\\Testing\\\\Testing.cs:line 74\",\"RemoteStackTraceString\":null,\"RemoteStackIndex\":0,\"ExceptionMethod\":\"8\\u000aThrowServerException\\u000aInSite8WebServiceLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\\u000aInSite8WebServiceLib.Testing\\u000aVoid ThrowServerException()\",\"HResult\":-2146232832,\"Source\":\"InSite8WebServiceLib\",\"WatsonBuckets\":null}"
…类型信息以类名条目的形式嵌入,DataContractJsonSerializer无法正确反序列化


所以我的问题是。为什么对于单个WCF WebHttp端点,多个WebInvoke属性化方法会返回几种不同格式的JSON,而DataContractJsonSerializer只能反序列化其中一种格式,如何修复它以使其正常工作?

可以通过重载构造函数强制DataContractJsonSerializer始终发出类型信息。然后将alwaysEmitTypeInformation参数设置为True


关于

的更多信息我已经看过那页了,后来发现它很混乱。在WCF服务的上下文中,服务