gpt4 book ai didi

c# - WCF JSON 反序列化中的空格问题

转载 作者:行者123 更新时间:2023-12-02 10:51:20 25 4
gpt4 key购买 nike

我有一个 WCF REST 服务,它接受 JSON 形式的自定义 DataContract 参数,该参数可以是父类(super class)型或子类型。当我传递包含额外空格的 JSON 时,该对象始终反序列化为父类(super class)型。当我从 JSON 中删除所有空格时,对象会反序列化为子类型。

这是一个例子:

[DataContract]
[KnownType(typeof(SubClass))]
public class SuperClass
{
[DataMember]
public string Message { get; set; }
}

[DataContract]
public class SubClass : SuperClass
{
[DataMember]
public string Extra { get; set; }
}

[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke]
void LogMessage(SuperClass arg);
}

public class Service1 : IService1
{
public void LogMessage(SuperClass arg)
{
if (arg is SubClass)
{
Debug.WriteLine("SubClass");
}
else if (arg is SuperClass)
{
Debug.WriteLine("SuperClass");
}
}
}

如果我发送以下消息,该服务将打印 SuperClass:

POST http://localhost:5763/Service1.svc/LogMessage HTTP/1.1
User-Agent: Fiddler
Content-Type: text/json
Host: localhost:5763
Content-Length: 86

{ "__type":"SubClass:#WhitespaceTest", "Message":"Message", "Extra":"Extra" }

如果我也“漂亮地打印”数据包,以便将 JSOn 分成多行,我会得到相同的结果。但是,如果我按如下方式删除空格,该服务将打印 SubClass:

POST http://localhost:5763/Service1.svc/LogMessage HTTP/1.1
User-Agent: Fiddler
Content-Type: text/json
Host: localhost:5763
Content-Length: 73

{"__type":"SubClass:#WhitespaceTest","Message":"Message","Extra":"Extra"}

我已经调试了 System.ServiceModel.OperationContext.Current.RequestContext.RequestMessage.ToString() 的输出,并注意到从 JSON 生成的 XML 在 2 个数据包之间是不同的:

<!-- First packet, deserializes to SuperClass -->
<root type="object">
<__type type="string">SubClass:#WhitespaceTest</__type>
<Message type="string">Message</Message>
<Extra type="string">Extra</Extra>
</root>

<!-- Second packet, deserializes to SubClass -->
<root type="object" __type="SubClass:#WhitespaceTest">
<Message type="string">Message</Message>
<Extra type="string">Extra</Extra>
</root>

因此,空白似乎混淆了 JSON 反序列化器。有谁知道为什么会发生这种情况以及我能做什么?

最佳答案

这是一个已知问题,已在 4.5 框架中修复。不幸的是,如果您想在当前框架版本中使用多态性,您实际上需要去除对象前面的空白。一种方法是使用 JsonReaderWriterFactory 创建的读取器/写入器读取/写入 JSON,因为它将去除元素周围的空白(或任何 pretty-print )。

public class StackOverflow_8661714
{
[DataContract(Name = "SuperClass", Namespace = "WhitespaceTest")]
[KnownType(typeof(SubClass))]
public class SuperClass
{
[DataMember]
public string Message { get; set; }
}

[DataContract(Name = "SubClass", Namespace = "WhitespaceTest")]
public class SubClass : SuperClass
{
[DataMember]
public string Extra { get; set; }
}
public static void Test()
{
string originalJson = "{ \"__type\":\"SubClass:WhitespaceTest\", \"Message\":\"Message\", \"Extra\":\"Extra\" }";
byte[] originalJsonBytes = Encoding.UTF8.GetBytes(originalJson);
MemoryStream writeStream = new MemoryStream();
XmlDictionaryWriter jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(writeStream, Encoding.UTF8, false);
XmlDictionaryReader jsonReader = JsonReaderWriterFactory.CreateJsonReader(originalJsonBytes, 0, originalJsonBytes.Length, XmlDictionaryReaderQuotas.Max);
jsonWriter.WriteNode(jsonReader, true);
jsonWriter.Flush();
Console.WriteLine(Encoding.UTF8.GetString(writeStream.ToArray()));
writeStream.Position = 0;

DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(SuperClass), new Type[] { typeof(SubClass) });
object o = dcjs.ReadObject(writeStream);
Console.WriteLine(o);
}
}

关于c# - WCF JSON 反序列化中的空格问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8661714/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com