C# WCF Json反序列化保留多态集合类型

C# WCF Json反序列化保留多态集合类型,c#,json,wcf,serialization,C#,Json,Wcf,Serialization,WCF Json反序列化 我正在使用Dotnet4.5在WCF中构建一个中间件webservice,该服务器返回一个多态类型 [DataContract] [KnownType(typeof(SomethingA))] [KnownType(typeof(SomethingB))] 公开课 { [数据成员] 公共int Item1{get;set;} [数据成员] 公共字符串Item2{get;set;} } [数据合同] A:什么 { } [数据合同] B:什么 { } /// ///测试各

WCF Json反序列化

我正在使用Dotnet4.5在WCF中构建一个中间件webservice,该服务器返回一个多态类型

[DataContract]
[KnownType(typeof(SomethingA))]
[KnownType(typeof(SomethingB))]
公开课
{
[数据成员]
公共int Item1{get;set;}
[数据成员]
公共字符串Item2{get;set;}
}
[数据合同]
A:什么
{ }
[数据合同]
B:什么
{ }
/// 
///测试各种web操作的服务合同。
/// 
[服务合同]
[ServiceKnownType(typeof(SomethingA))]
[ServiceKnownType(类型(SomethingB))]
公共接口测试
{
/// 
///使用POST和json测试传入和返回对象。
/// 
[经营合同]
[WebInvoke(
RequestFormat=WebMessageFormat.Json,
ResponseFormat=WebMessageFormat.Json,
BodyStyle=WebMessageBodyStyle.Bare,
UriTemplate=“使用多态某物”,
Method=“POST”)]
列出UsePolymorphicSomethings();
}
/// 
///实施ITesting服务合同。
/// 
公共类测试:ITesting
{
公共列表UsePolymorphicSomethings()
{
List retVal=新列表();
Add(newsomethinga{Item1=1,Item2=“1”});
Add(newsomethingb{Item1=1,Item2=“1”});
返回返回;
}
}
在客户端,我试图以一种保留集合中不同类型的方式对其进行反序列化。在我看来,这方面的MSDN文档非常薄弱。我遇到的第一个问题是,添加对System.Web.Http的引用会在名为Newtonsoft.Json的第三方开源组件上创建一个未记录的动态依赖项,我必须从Web下载该组件

前两种反序列化方法都失败了,但我发现第三种方法是有效的

我想知道的是为什么前两种方法失败了?理想情况下,我希望得到第一种工作方法,因为这是最精简的

[TestMethod]
public void usemorphicsomethings_Test1()
{
使用(HttpClient http=newhttpclient())
{
http.BaseAddress=新Uri(“http://localhost:8733/");
HttpResponseMessage响应=http.PostAsJsonAsync(
“设计\时间\地址/InSite8WebServiceLib2/测试/使用多态某物”,
新的StringContent(string.Empty)).Result;
List ret=response.Content.ReadAsAsync().Result;
//失败了。
AreEqual(typeof(SomethingA),something[0].GetType());
AreEqual(typeof(SomethingB),somethings[1].GetType());
}
}
[测试方法]
public void usemorphicsomethings_Test2()
{
使用(HttpClient http=newhttpclient())
{
http.BaseAddress=新Uri(“http://localhost:8733/");
HttpResponseMessage响应=http.PostAsJsonAsync(
“设计\时间\地址/InSite8WebServiceLib2/测试/使用多态某物”,
新的StringContent(string.Empty)).Result;
字符串ret1=response.Content.ReadAsStringAsync().Result;
Newtonsoft.Json.JsonSerializerSettings=new Newtonsoft.Json.JsonSerializerSettings();
s、 TypeNameHandling=Newtonsoft.Json.TypeNameHandling.All;
List r=Newtonsoft.Json.JsonConvert.DeserializeObject(ret1,s);
//失败了。
AreEqual(typeof(SomethingA),something[0].GetType());
AreEqual(typeof(SomethingB),somethings[1].GetType());
}
}
[测试方法]
public void usemorphicsomethings_Test3()
{
使用(HttpClient http=newhttpclient())
{
http.BaseAddress=新Uri(“http://localhost:8733/");
HttpResponseMessage响应=http.PostAsJsonAsync(
“设计\时间\地址/InSite8WebServiceLib2/测试/使用多态某物”,
新的StringContent(string.Empty)).Result;
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 T Deserialize<T>(Stream stream) where T : class
    {
        var serializer = new DataContractJsonSerializer(typeof(T));
        return (T)serializer.ReadObject(stream);
    }
public T反序列化(流),其中T:class
{
var serializer=newdatacontractjsonserializer(typeof(T));
return(T)serializer.ReadObject(stream);
}
然后,您可以像这样简单地调用此方法

List<Something> somethings = Deserialize<List<Something>>(stream);
List something=反序列化(流);
为了让事情在某种意义上更简单,您可以将helper方法作为扩展方法编写, 像这样的

public static class Helpers
{
    public static T Deserialize<T>(this Stream stream) where T : class
    {
        var serializer = new DataContractJsonSerializer(typeof(T));
        return (T)serializer.ReadObject(stream);
    }
}
var result = stream.Deserialize<List<Something>>();
var result = response.Deserialize<List<Something>>();
公共静态类帮助程序
{
公共静态T反序列化(此流),其中T:class
{
var serializer=newdatacontractjsonserializer(typeof(T));
return(T)serializer.ReadObject(stream);
}
}
然后可以这样调用此方法

public static class Helpers
{
    public static T Deserialize<T>(this Stream stream) where T : class
    {
        var serializer = new DataContractJsonSerializer(typeof(T));
        return (T)serializer.ReadObject(stream);
    }
}
var result = stream.Deserialize<List<Something>>();
var result = response.Deserialize<List<Something>>();
var result=stream.Deserialize();
要继续,您可以针对HttpResponseMessage创建扩展方法

public static class Helpers
{
    public static T Deserialize<T>(this HttpResponseMessage response) where T : class
    {
        var stream = response.Content.ReadAsStreamAsync().Result;
        var serializer = new DataContractJsonSerializer(typeof(T));
        return (T)serializer.ReadObject(stream);
    }
}
公共静态类帮助程序
{
公共静态T反序列化(此HttpResponseMessage响应),其中T:class
{
var stream=response.Content.ReadAsStreamAsync().Result;
var serializer=newdatacontractjsonserializer(typeof(T));
return(T)serializer.ReadObject(stream);
}
}
您可以这样调用此方法

public static class Helpers
{
    public static T Deserialize<T>(this Stream stream) where T : class
    {
        var serializer = new DataContractJsonSerializer(typeof(T));
        return (T)serializer.ReadObject(stream);
    }
}
var result = stream.Deserialize<List<Something>>();
var result = response.Deserialize<List<Something>>();
var result=response.Deserialize();
至少您的代码现在将再次成为