C# __WCFService的类型和继承

C# __WCFService的类型和继承,c#,json,wcf,C#,Json,Wcf,当我使用Postman chrome发送请求时,如果我不将_类型添加为“_类型”:“BusTextMessage:#TransportModels.Messages”对象将无法正确序列化,因为它不知道如何实例化BusMessage类。我已经定义了Type属性,它定义了消息的类型。是否有可能重写类型行为,例如根据类型属性返回正确的实现?我不希望任何人手动将_类型信息放入json,那么在反序列化之前是否可以编辑json,如果不存在,是否可以手动将_类型属性添加到json?例如,我想做这样的事情:

当我使用Postman chrome发送请求时,如果我不将_类型添加为“_类型”:“BusTextMessage:#TransportModels.Messages”对象将无法正确序列化,因为它不知道如何实例化BusMessage类。我已经定义了Type属性,它定义了消息的类型。是否有可能重写类型行为,例如根据类型属性返回正确的实现?我不希望任何人手动将_类型信息放入json,那么在反序列化之前是否可以编辑json,如果不存在,是否可以手动将_类型属性添加到json?例如,我想做这样的事情:

    [DataContract]
    public abstract  class BusMessage
    {
        [DataMember(Name = "encoding")]
        public string Encoding { get; set; }

        [DataMember(Name = "type")]
        public virtual MessageType Type
        {
            get { return _type; }
            private set { _type = value; }
        }
    }

[DataContract]
public class BusTextMessage : BusMessage
{
    [DataMember(Name = "type")]
    public override MessageType Type
    {
        get { return MessageType.Text; }
    }

    [DataMember(Name = "payload")]
    public string Payload { get; set; }
}




    [ServiceContract]
    [ServiceKnownType("GetKnownTypes", typeof(Helper))]
    public interface ICommunicationService
    {
        [WebInvoke(Method = "POST",
            ResponseFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Bare,
            UriTemplate = "/SendMessage")]
        string SendMessage(BusMessage jsonMessage);
    }
}
我找到了这种方法,但似乎不可用:

public void BeforeDeserialization(string json)
{
       if(json doesnt include __type)
       {
           if(json property type(my property) is MessageType.Text)
            add to json "__type":"BusTextMessage:#TransportModels.Messages"

       ///etc
       }
}

我认为您需要将KnownType属性添加到BusMessage类中

 [OnDeserializing()]
        internal void OnDeserializingMethod(StreamingContext context)
        {

        }

这是我发现的最快的解决方案。我配置MessageInspector并处理AfterReceiveRequest。然后检查消息格式(XML、JSON)。如果它是XML(例如,从任何用C#编写的WCF客户端发送,WCF配置为使用XML发送所有内容),那么我接受该消息,因为WCF机制将自动插入字段类型。否则,我会检查它是否是JSON,例如从外部客户端发送的JSON。如果它不包含属性“\uuuuu type”,我将检查我的属性类型并生成适当的\uuuu类型值。例如,如果我的类型等于Text,我将添加uu Type属性BusTextMessage:#TransportModels.Messages并将其插入JSON,然后重新创建消息。我找不到更快更简单的解决方案,它似乎正在发挥作用。处理我在找到的收件人后的请求

公共类MessageTypeInspector:IDispatchMessageInspector
{
接收请求后的公共对象(ref消息请求、IClientChannel通道、InstanceContext InstanceContext)
{
重新创建消息(ref请求);
返回null;
}
}
私有void重新创建消息(参考消息消息消息)
{
WebContentFormat messageFormat=此.GetMessageContentFormat(消息);
var ms=新内存流();
XmlDictionaryWriter writer=null;
开关(消息格式)
{
案例WebContentFormat。默认值:
案例WebContentFormat.Xml:
writer=XmlDictionaryWriter.CreateTextWriter(毫秒);
打破
案例WebContentFormat.Json:
writer=JsonReaderWriterFactory.CreateJsonWriter(ms);
打破
案例WebContentFormat.Raw:
此.ReadRawBody(ref消息);
打破
}
message.WriteMessage(编写器);
writer.Flush();
string messageBody=Encoding.UTF8.GetString(ms.ToArray());
if(messageFormat==WebContentFormat.Json&&!messageBody.Contains(“\uu类型”))
messageBody=AddTypeField(messageBody);
ms.Position=0;
ms=newmemoryStream(Encoding.UTF8.GetBytes(messageBody));
XmlDictionaryReader=messageFormat==WebContentFormat.Json?
JsonReaderWriterFactory.CreateJsonReader(ms,XmlDictionaryReaderQuotas.Max):
CreateTextReader(ms,xmldirectionaryReaderquotas.Max);
Message newMessage=Message.CreateMessage(reader,int.MaxValue,Message.Version);
newMessage.Properties.CopyProperties(message.Properties);
消息=新消息;
}
私有WebContentFormat GetMessageContentFormat(消息消息)
{
WebContentFormat=WebContentFormat.Default;
if(message.Properties.ContainsKey(WebBodyFormatMessageProperty.Name))
{
WebBodyFormatMessageProperty bodyFormat;
bodyFormat=(WebBodyFormatMessageProperty)message.Properties[WebBodyFormatMessageProperty.Name];
format=bodyFormat.format;
}
返回格式;
}
私有字符串AddTypeField(字符串jsonReply)
{
var typeRegex=newregex(“\”type\”:(?[0-9]*)”;
Match Match=typeRegex.Match(jsonReply);
如果(匹配成功)
{
int number=Int32.Parse(match.Groups[“number”].Value);
变量类型=(消息类型)编号;
var nameFormat=string.Format(“总线{0}消息”,类型);
string format=string.format(“\”\uu type\”:\“{0}:\35; TransportModels.Messages\”,nameFormat);
jsonReply=“{”+string.Format(“{0},{1}”,Format,jsonReply.Substring(1));
返回jsonReply;
}
其他的
{
抛出新异常(“错误的消息类型”);
}
}

这不是我问题的答案。此外,在WCFService中添加它就足够了
[DataContract]
[KnownType(typeof(BusTextMessage)]
public class BusMessage
{
.
.
.
}
  public class MessageTypeInspector : IDispatchMessageInspector
   {
        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext                 instanceContext)
        {
           RecreateMessage(ref request);
            return null;
        }
   }





private void RecreateMessage(ref Message message)
        {
            WebContentFormat messageFormat = this.GetMessageContentFormat(message);
            var ms = new MemoryStream();
            XmlDictionaryWriter writer = null;
            switch (messageFormat)
            {
                case WebContentFormat.Default:
                case WebContentFormat.Xml:
                    writer = XmlDictionaryWriter.CreateTextWriter(ms);
                    break;
                case WebContentFormat.Json:
                    writer = JsonReaderWriterFactory.CreateJsonWriter(ms);
                    break;
                case WebContentFormat.Raw:
                   this.ReadRawBody(ref message);
                    break;
            }

            message.WriteMessage(writer);
            writer.Flush();
            string messageBody = Encoding.UTF8.GetString(ms.ToArray());

            if (messageFormat == WebContentFormat.Json && !messageBody.Contains("__type"))
                messageBody = AddTypeField(messageBody);

            ms.Position = 0;


            ms = new MemoryStream(Encoding.UTF8.GetBytes(messageBody));

            XmlDictionaryReader reader = messageFormat == WebContentFormat.Json ?
                JsonReaderWriterFactory.CreateJsonReader(ms, XmlDictionaryReaderQuotas.Max) :
                XmlDictionaryReader.CreateTextReader(ms, XmlDictionaryReaderQuotas.Max);

            Message newMessage = Message.CreateMessage(reader, int.MaxValue, message.Version);
            newMessage.Properties.CopyProperties(message.Properties);
            message = newMessage;

        }

 private WebContentFormat GetMessageContentFormat(Message message)
        {
            WebContentFormat format = WebContentFormat.Default;
            if (message.Properties.ContainsKey(WebBodyFormatMessageProperty.Name))
            {
                WebBodyFormatMessageProperty bodyFormat;
                bodyFormat = (WebBodyFormatMessageProperty)message.Properties[WebBodyFormatMessageProperty.Name];
                format = bodyFormat.Format;
            }

            return format;
        }

private string AddTypeField(string jsonReply)
        {
            var typeRegex = new Regex("\"type\":(?<number>[0-9]*)");

            Match match = typeRegex.Match(jsonReply);
            if (match.Success)
            {
                int number = Int32.Parse(match.Groups["number"].Value);
                var type = (MessageType)number;
                var nameFormat = string.Format("Bus{0}Message", type);
                string format = string.Format("\"__type\":\"{0}:#TransportModels.Messages\"", nameFormat);
                jsonReply = "{" + string.Format("{0},{1}", format, jsonReply.Substring(1));
                return jsonReply;
            }
            else
            {
                throw new Exception("Wrong message type.");
            }
        }