Stream 带Soap扩展的ASMX web服务-加密方法存在问题

Stream 带Soap扩展的ASMX web服务-加密方法存在问题,stream,asmx,soap-extension,Stream,Asmx,Soap Extension,我尝试在ASP.NETWeb服务中对SOAP消息进行加密 //I have Crypt class, which input parameters is Stream: public class CryptUtility { public virtual Stream EncryptAndSingXml (Stream inputStream) { XmlTextReader reader = new XmlTextReader(inputStream

我尝试在ASP.NETWeb服务中对SOAP消息进行加密

//I have Crypt class, which input parameters is Stream:
public class CryptUtility
 {
      public virtual Stream EncryptAndSingXml (Stream inputStream)
      {
         XmlTextReader reader = new XmlTextReader(inputStream);
         XmlDocument doc = new XmlDocument();
         doc.Load(reader);

         // in this place I encrypt and sign SOAP message
         foreach (string xPathQuery in soapElement)
          {
          XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
            foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
              {
                // method EncryptString crypt only string from XmlNode
                nodeToEncrypt.InnerXml = EncryptString();
              }
           }

         // !!!
         //               I        THINK  HERE IS A PROBLEM 
         //
         //it return plain stream, no encrypt stream
         MemoryStream retStream = new MemoryStream();
         XmlTextWriter writer = new XmlTextWriter(retStream, Encoding.UTF8);
         doc.Save(retStream);
         return retStream;
      }
 }
我在Soap扩展类中使用了CryptUtility对象:

public class SoapMsg : SoapExtension
 {
     private CryptUtility cryptUtil; //this object crypt and sing SOAP message
     //  ...

     //this method copy stream
     private void CopyStream(Stream from, Stream to)
     {
     TextReader reader = new StreamReader(from);
     TextWriter writer = new StreamWriter(to);
     writer.Write(reader.ReadToEnd());
     writer.Flush();
     }

     //this method sing and encrypt SOAP message, I call this method in stage  AfterSerialize
     private void CryptMessage()
     {
     newStream.Position = 0;
     Stream retStream = cryptUtil.EncryptAndSingXml(newStream);
     retStream.Position = 0;
     CopyStream(retStream, oldStream);
     }

     public override void ProcessMessage(SoapMessage message)
     {
       switch (message.Stage)
         {
           case SoapMessageStage.BeforeSerialize:
              break;
           case SoapMessageStage.AfterSerialize:
           {
           // call the crypt and sing method
           CryptMessage();
           //save the SOAP message, the message is not encrypt
           Log(message, "AfterSerialize");
           }
             break;
           case SoapMessageStage.BeforeDeserialize:
              break;
           case SoapMessageStage.AfterDeserialize:
               break;
            default:
              throw new ArgumentException("error.");
           }

        }
     // ...
 }
问题是,当我在反序列化后记录SOAP消息时,XML是纯文本,但它应该是加密的 谁能帮帮我,哪里有问题,或者我能做什么坏事

因为首先我在SoapMsg类中使用方法EncryptAndSingXml作为void,它工作正常 大概是这样的:

 public class SoapMsg : SoapExtension
 {
 //...
      public void EncryptAndSingXml()
      {...}
 //...
     public override void ProcessMessage(SoapMessage message)
     {
       switch (message.Stage)
         {
           //...
           case SoapMessageStage.AfterSerialize:
           EncryptAndSingXml();
               break;
           //...
        }
     // ...
 }
但当我将C类CryptUtility和方法EncryptAndSingXml()设为虚拟时,它就不起作用了:(
有人能帮我吗?

看起来你根本没有在修改
消息

并且,请显示在何处创建
CryptUtility
的实例

此外,您的代码非常糟糕。请尝试以下操作:

public class CryptUtility
{
    public virtual Stream EncryptAndSingXml(Stream inputStream, IEnumerable<string> soapElement)
    {
        XmlDocument doc = new XmlDocument();
        using (XmlReader reader = XmlReader.Create(inputStream))
        {
            doc.Load(reader);
        }

        // in this place I encrypt and sign SOAP message
        XmlNamespaceManager nsMan = new XmlNamespaceManager(doc.NameTable);
        foreach (string xPathQuery in soapElement)
        {
            XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
            foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
            {
                // method EncryptString crypt only string from XmlNode
                nodeToEncrypt.InnerXml = EncryptString(nodeToEncrypt.InnerXml);
            }
        }

        // !!!
        //               I        THINK  HERE IS A PROBLEM 
        //
        //it return plain stream, no encrypt stream
        using (MemoryStream retStream = new MemoryStream())
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = Encoding.UTF8;
            using (XmlWriter writer = XmlWriter.Create(retStream, settings))
            {
                doc.WriteTo(writer);
            }
            return retStream;
        }
    }
}

看起来您根本没有在修改
消息

并且,请显示在何处创建
CryptUtility
的实例

此外,您的代码非常糟糕。请尝试以下操作:

public class CryptUtility
{
    public virtual Stream EncryptAndSingXml(Stream inputStream, IEnumerable<string> soapElement)
    {
        XmlDocument doc = new XmlDocument();
        using (XmlReader reader = XmlReader.Create(inputStream))
        {
            doc.Load(reader);
        }

        // in this place I encrypt and sign SOAP message
        XmlNamespaceManager nsMan = new XmlNamespaceManager(doc.NameTable);
        foreach (string xPathQuery in soapElement)
        {
            XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
            foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
            {
                // method EncryptString crypt only string from XmlNode
                nodeToEncrypt.InnerXml = EncryptString(nodeToEncrypt.InnerXml);
            }
        }

        // !!!
        //               I        THINK  HERE IS A PROBLEM 
        //
        //it return plain stream, no encrypt stream
        using (MemoryStream retStream = new MemoryStream())
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = Encoding.UTF8;
            using (XmlWriter writer = XmlWriter.Create(retStream, settings))
            {
                doc.WriteTo(writer);
            }
            return retStream;
        }
    }
}

我在Initialize中创建instace CryptUtility。感谢您的帮助,它可以工作。使用的原因是什么?例如:使用(XmlReader reader=XmlReader.create(inputStream)){doc.Load(reader);}我只使用ASP.NET一个月。
使用
在创建实现
IDisposable
的类型实例时使用。它确保即使引发异常也调用
IDisposable.Dispose
。规则是-如果创建此类类型的实例,应使用
块将其包装在
中。谢谢advance。从现在起,如果我的instance实现了iterface IDisposable,我将使用创建实例。我在Initialize中创建instace CryptUtility。感谢advance,它可以工作。使用的原因是什么?例如:使用(XmlReader reader=XmlReader.create(inputStream)){doc.Load(reader);}我只使用ASP.NET一个月。
使用
在创建实现
IDisposable
的类型实例时使用。它确保即使引发异常也调用
IDisposable.Dispose
。规则是-如果创建此类类型的实例,应使用
块将其包装在
中。谢谢从现在起,如果我的instance实现了iterface IDisposable,我将使用创建实例。