如何:c#XML InfoSet到JSON

时间:2017-02-02 19:53:48

标签: c# json xml wcf wcf-extensions

因此,WCF采用JSON,无论出于何种原因将其转换为XML Infoset(请参阅:https://stackoverflow.com/a/5684703/497745)。然后它使用JsonReaderDelegator在内部读回这个XML Infoset(参见:https://referencesource.microsoft.com/#System.Runtime.Serialization/System/Runtime/Serialization/Json/JsonReaderDelegator.cs,c0d6a87689227f04)。

我正在对WCF执行流进行一些非常深入的修改,我需要将XML Infoset转换回原始的JSON。

是否有.NET或外部的库可以使用WCF生成的XML Infoset并将其转换回原来的JSON?

1 个答案:

答案 0 :(得分:0)

找到一个适用于我的方案的答案,并进行了一些有限的修改。

本文:https://blogs.msdn.microsoft.com/carlosfigueira/2011/04/18/wcf-extensibility-message-inspectors/解释了如何记录最初进入WCF的JSON,即使它仅作为XML InfoSet公开。这是关键的洞察力。具体来说,看看它的MessageToString实现。

下面是我的代码的相关部分,基于上面链接中的MessageToString的实现,在我编写的类internal class MessageFormatInspector : IDispatchMessageInspector, IEndpointBehavior中运行以注入到WCF堆栈中:

public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
   ...
   var s = GetJsonFromMessage(request);
   ...
}

private static string GetJsonFromMessage(ref Message request)
{

    using (MemoryStream ms = new MemoryStream())
    {
        using (XmlDictionaryWriter writer = JsonReaderWriterFactory.CreateJsonWriter(ms))
        {
            request.WriteMessage(writer);
            writer.Flush();
            string json = Encoding.UTF8.GetString(ms.ToArray()); //extract the JSON at this point

            //now let's make our copy of the message to support the WCF pattern of rebuilding messages after consuming the inner stream (see: https://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.idispatchmessageinspector.afterreceiverequest(v=vs.110).aspx and https://blogs.msdn.microsoft.com/carlosfigueira/2011/05/02/wcf-extensibility-message-formatters/)
            ms.Position = 0; //Rewind. We're about to make a copy and restore the message we just consumed.

            XmlDictionaryReader reader = JsonReaderWriterFactory.CreateJsonReader(ms, XmlDictionaryReaderQuotas.Max); //since we used a JsonWriter, we read the data back, we need to use the correlary JsonReader.

            Message restoredRequestCopy = Message.CreateMessage(reader, int.MaxValue, request.Version); //now after a lot of work, create the actual copy
            restoredRequestCopy.Properties.CopyProperties(request.Properties); //copy over the properties
            request = restoredRequestCopy;
            return json;
        }
    }
}

不幸的是,上面的代码只能在WCF消息检查器的上下文中使用。

但是,它可以使用XMLDictionary,它具有XML InfoSet,并使用WCF自己内置的JsonWriter来反转WCF所做的转换并发出原始的JSON。

我希望这可以帮助别人节省一些时间。