升级环境以从.NET 4.6
定位.NET 4.0
框架后,当外部调用AuditSoap
时,它会引用空requestSoapMessage
对象,因为看起来似乎是ChainStream
程序未初始化。
.NET 4.6
处理SOAP的方式与先前版本的框架不同吗?当我逐步浏览.NET 4.0
上的代码时,它按预期工作,初始化ChainStream
过程(然后调用ProcessMessage
)。这不会发生在.NET 4.6
上 - 代码库在升级之间没有变化,因此我认为问题必须与.NET 4.6
处理它的方式有关。
private static XmlDocument xmlRequest;
/// Gets the outgoing XML request
public static XmlDocument XmlRequest
{ get { return xmlRequest; } }
private static XmlDocument xmlResponse;
/// Gets the incoming XML response
public static XmlDocument XmlResponse
{ get { return xmlResponse; } }
private static SoapMessage requestSoapMessage;
/// Gets the outgoing soap message
public static SoapMessage RequestSoapMessage
{ get { return requestSoapMessage; } }
private static SoapMessage responseSoapMessage;
/// Gets the incoming soap message
public static SoapMessage ResponseSoapMessage
{ get { return responseSoapMessage; } }
/// Save the Stream representing the SOAP request
/// or SOAP response into a local memory buffer.
public override Stream ChainStream(Stream stream)
{
oldStream = stream;
newStream = new MemoryStream();
return newStream;
}
/// If the SoapMessageStage is such that the SoapRequest or
/// SoapResponse is still in the SOAP format to be sent or received,
/// save it to the xmlRequest or xmlResponse property.
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.BeforeSerialize:
break;
case SoapMessageStage.AfterSerialize:
xmlRequest = GetSoapEnvelope(newStream);
CopyStream(newStream, oldStream);
requestSoapMessage = message;
break;
case SoapMessageStage.BeforeDeserialize:
CopyStream(oldStream, newStream);
xmlResponse = GetSoapEnvelope(newStream);
responseSoapMessage = message;
break;
case SoapMessageStage.AfterDeserialize:
break;
}
}
public void AuditSoap()
{
try
{
string action = System.Web.HttpContext.Current.Request.RequestContext.RouteData.GetRequiredString("action");
//log the Request
logService.Audit(true,
LogArea.Data,
requestSoapMessage.MethodInfo.Name,
"Request",
action,
XmlRequest.InnerXml,
null,
null,
null,
XmlRequest.InnerXml);
//log the response
logService.Audit(true,
LogArea.Data,
responseSoapMessage.MethodInfo.Name,
"Response",
action,
XmlResponse.InnerXml,
null,
null,
null,
XmlResponse.InnerXml);
}
catch (Exception ex)
{
Trace.TraceError("Error in logging the web service.\n{0}", ex.ToJson());
}
}
/// Returns the XML representation of the Soap Envelope in the supplied stream.
/// Resets the position of stream to zero.
private XmlDocument GetSoapEnvelope(Stream stream)
{
XmlDocument xml = new XmlDocument();
stream.Position = 0;
StreamReader reader = new StreamReader(stream);
xml.LoadXml(reader.ReadToEnd());
stream.Position = 0;
return xml;
}
/// Copies a stream.
private void CopyStream(Stream from, Stream to)
{
TextReader reader = new StreamReader(from);
TextWriter writer = new StreamWriter(to);
writer.WriteLine(reader.ReadToEnd());
writer.Flush();
}
/// Included only because it must be implemented.
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
return null;
}
/// Included only because it must be implemented.
public override object GetInitializer(Type WebServiceType)
{
return null;
}
/// Included only because it must be implemented.
public override void Initialize(object initializer)
{
}