C# 如何修改WCF Soap消息体响应

C# 如何修改WCF Soap消息体响应,c#,xml,web-services,wcf,soap,C#,Xml,Web Services,Wcf,Soap,我有下面的WCF服务,它接受和SOAP消息,我希望它返回SOAP消息响应 [ServiceContract] public interface IMyService { [OperationContract(Action = "HotelAvailRQ", ReplyAction = "HotelAvailRQResponse")] [WebInvoke(Method = "POST", BodyStyle =

我有下面的WCF服务,它接受和SOAP消息,我希望它返回SOAP消息响应

    [ServiceContract]
    public interface IMyService
    {          
       [OperationContract(Action = "HotelAvailRQ", ReplyAction = "HotelAvailRQResponse")]
       [WebInvoke(Method = "POST",
       BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml)]
       Message HotelAvailRQ(Message message);       
    }

    public class MyService : IMyService
    {
       public Message HotelAvailRQ(Message message)
       {
           return ProcessMessage<OTA_HotelAvailRQ>(message);
       }

       public Message ProcessMessage<T>(Message message)
       {
           MessageBuffer buffer = message.CreateBufferedCopy(8192);

           // Get a copy of the original message. This will be used to read and extract the body.
           Message msgCopy = buffer.CreateMessage();

           // Take another copy of the same message. This will be used to return to the service. Returning an identical message forms part of the acknowledgement in this case.
           Message returnMsg = buffer.CreateMessage();

           XElement body = XElement.Parse(msgCopy.GetReaderAtBodyContents().ReadOuterXml());
           var instance = Deserialize<T>(body, "http://www.opentravel.org/OTA/2003/05");

           MethodInfo methodInfo = typeof(T).GetMethod("Process");
           object document = methodInfo.Invoke(instance, null);

           return returnMsg;

       }

       private static T Deserialize<T>(XElement xElement, string nameSpace)
       {
           using (MemoryStream memoryStream = new MemoryStream(Encoding.ASCII.GetBytes(xElement.ToString())))
           {
               XmlSerializer xmlSerializer = new XmlSerializer(typeof(T), nameSpace);
               return (T)xmlSerializer.Deserialize(memoryStream);
           }
       }

       private static string Serialize(object obj)
       {
           using (MemoryStream memoryStream = new MemoryStream())
           {
               XmlSerializer xs = new XmlSerializer(obj.GetType());
               xs.Serialize(memoryStream, obj);
               return ASCIIEncoding.ASCII.GetString(memoryStream.ToArray());
           }
       }
   }  

   public partial class OTA_HotelAvailRQ
   {
       public static object Process()
       {
           try
           {
               OTA_HotelAvailRQ hotelAvailRQ = new OTA_HotelAvailRQ();
               //Do some stuff and return back new object
               return hotelAvailRQ ;
           }
           catch(Exception ex)
           {            
               return new OTA_HotelAvailRS(); //TODO Should be fault exception...
           }
       }
   }
[服务合同]
公共接口IMyService
{          
[运营合同(Action=“HotelAvailRQ”,ReplyAction=“HotelAvailRQResponse”)]
[WebInvoke(Method=“POST”,
BodyStyle=WebMessageBodyStyle.Bare,RequestFormat=WebMessageFormat.Xml)]
消息HotelAvailRQ(消息消息);
}
公共类MyService:IMyService
{
公共消息HotelAvailerQ(消息消息)
{
返回ProcessMessage(message);
}
公共消息处理消息(消息消息)
{
MessageBuffer=message.CreateBufferedCopy(8192);
//获取原始邮件的副本。这将用于读取和提取正文。
Message msgCopy=buffer.CreateMessage();
//获取同一消息的另一份副本。这将用于返回服务。在这种情况下,返回相同的消息构成确认的一部分。
Message returnMsg=buffer.CreateMessage();
XElement body=XElement.Parse(msgCopy.GetReaderAtBodyContents().ReadOuterXml());
var instance=反序列化(正文,“http://www.opentravel.org/OTA/2003/05");
MethodInfo MethodInfo=typeof(T).GetMethod(“过程”);
objectdocument=methodInfo.Invoke(实例,null);
returnMsg;
}
私有静态T反序列化(XElement XElement,字符串命名空间)
{
使用(MemoryStream MemoryStream=new MemoryStream(Encoding.ASCII.GetBytes(xElement.ToString()))
{
XmlSerializer XmlSerializer=新的XmlSerializer(typeof(T),名称空间);
返回(T)xmlSerializer.Deserialize(memoryStream);
}
}
私有静态字符串序列化(对象obj)
{
使用(MemoryStream MemoryStream=new MemoryStream())
{
XmlSerializer xs=新的XmlSerializer(obj.GetType());
序列化(memoryStream,obj);
返回ascienceoding.ASCII.GetString(memoryStream.ToArray());
}
}
}  
公共部分类OTA_HotelAvailerq
{
公共静态对象进程()
{
尝试
{
OTA_HotelAvailRQ HotelAvailRQ=新的OTA_HotelAvailRQ();
//做一些事情并返回新对象
返回HotelAvailerQ;
}
捕获(例外情况除外)
{            
返回新的OTA_HotelAvailers();//TODO应该是错误异常。。。
}
}
}
我是否需要修改传入的SOAP消息以及我的身体响应?如果是,我如何修改响应,或创建新的SOAP消息响应

更新:

我尝试了@popo的建议,结果

   var respObj = new object(); //resposneObjBody
   var settings = new XmlReaderSettings
   {
       IgnoreWhitespace = true
   };

   using (MemoryStream ms = new MemoryStream())
   {
       XmlSerializer xs = new XmlSerializer(respObj.GetType());
       xs.Serialize(ms, respObj);
       ms.Position = 0; '<< Added
       var reader = XmlReader.Create(ms, settings);
       var newMessage = Message.CreateMessage(reader, int.MaxValue, msgCopy.Version);
       newMessage.Headers.Clear();
       newMessage.Headers.CopyHeadersFrom(msgCopy.Headers);
   }
var respObj=新对象()//反应体
var设置=新的XmlReaderSettings
{
IgnoreWhitespace=true
};
使用(MemoryStream ms=new MemoryStream())
{
XmlSerializer xs=新的XmlSerializer(respObj.GetType());
序列化(ms,respObj);

ms.Position=0;“不确定这是否有用,但如果没有,我将删除答案,也许其他人会有更启发性的东西。这是我在消息检查器中使用的一些代码的修改版本,用于操作消息并将其传递给操作。 (以下未经测试):


我认为您可以创建一条新消息,使用原始消息的消息版本,从原始消息复制消息头,并从响应中添加内容,这可能比尝试修改请求消息更容易。创建消息时有多个重载。
message.CreateMessage(…
我根据您的建议更新了我的问题,但出现了“无法识别的邮件版本”的例外情况。有什么想法吗,因为我们使用的是原始邮件version@Tommassiov我更新了我的答案,我想这会对你有用。我不确定你的回复邮件是否需要原始邮件的标题和属性,likel不,希望有帮助:)
    var respObj = new object(); //resposneObjBody you have to define this object type added just for filler
    var settings = new XmlReaderSettings
    {
        IgnoreWhitespace = true
    };

    using (MemoryStream ms = new MemoryStream())
    {
            XmlSerializer xs = new XmlSerializer(respObj.GetType());
            xs.Serialize(ms, respObj);
            ms.Position = 0; 
            var reader = XmlReader.Create(ms, settings);
            var newMessage = Message.CreateMessage(msgCopy.Version, null, reader); // action is null, but you may want to put your reply action here
            newMessage.Headers.Clear(); //you may not need this either
            newMessage.Headers.CopyHeadersFrom(msgCopy.Headers); //you may not need this either
            newMessage.Properties.CopyProperties(msgCopy.Properties); //optional??
    }