Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.NET SoapExtension无法修改服务器上的soap请求_.net_Soap Extension - Fatal编程技术网

.NET SoapExtension无法修改服务器上的soap请求

.NET SoapExtension无法修改服务器上的soap请求,.net,soap-extension,.net,Soap Extension,我正在尝试在.NET中实现一个soap扩展,它将压缩所有soap通信(请求和响应)。我可以控制客户端和服务器。我从复制这个开始:稍微修改一下,我遇到了一个问题 当请求主体从客户端发送到服务器时,我能够修改(zip)请求主体,反向操作(解压)也可以,但我似乎无法让框架反映我对流对象所做的更改!在服务器上,我为newStream对象设置了正确的数据,但是当调用WebMethod时,参数仍然压缩(因此无效)。知道为什么吗 为了让包括我在内的每个人都更容易,我将SoapExtension简化为: usi

我正在尝试在.NET中实现一个soap扩展,它将压缩所有soap通信(请求和响应)。我可以控制客户端和服务器。我从复制这个开始:稍微修改一下,我遇到了一个问题

当请求主体从客户端发送到服务器时,我能够修改(zip)请求主体,反向操作(解压)也可以,但我似乎无法让框架反映我对流对象所做的更改!在服务器上,我为newStream对象设置了正确的数据,但是当调用WebMethod时,参数仍然压缩(因此无效)。知道为什么吗

为了让包括我在内的每个人都更容易,我将SoapExtension简化为:

using System;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.IO;
using System.Net;

// Define a SOAP Extension that traces the SOAP request and SOAP
// response for the XML Web service method the SOAP extension is
// applied to.

public class TraceExtension : SoapExtension {
Stream oldStream;
Stream newStream;
string filename;

// 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;
}

// When the SOAP extension is accessed for the first time, the XML Web
// service method it is applied to is accessed to store the file
// name passed in, using the corresponding SoapExtensionAttribute.  
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
    return ((TraceExtensionAttribute)attribute).Filename;
}

// The SOAP extension was configured to run using a configuration file
// instead of an attribute applied to a specific XML Web service
// method.
public override object GetInitializer(Type WebServiceType)
{
    // Return a file name to log the trace information to, based on the
    // type.
    return "C:\\" + WebServiceType.FullName + ".log";
}

// Receive the file name stored by GetInitializer and store it in a
// member variable for this specific instance.
public override void Initialize(object initializer)
{
    filename = (string)initializer;
}

//  If the SoapMessageStage is such that the SoapRequest or
//  SoapResponse is still in the SOAP format to be sent or received,
//  save it out to a file.
public override void ProcessMessage(SoapMessage message)
{
    switch (message.Stage)
    {
        case SoapMessageStage.BeforeSerialize:
            break;
        case SoapMessageStage.AfterSerialize:
            WriteOutput(message);
            break;
        case SoapMessageStage.BeforeDeserialize:
            WriteInput(message);
            break;
        case SoapMessageStage.AfterDeserialize:
            break;
    }
}

public void WriteOutput(SoapMessage message)
{
    newStream.Position = 0;
    FileStream fs = new FileStream(filename, FileMode.Append,
        FileAccess.Write);
    StreamWriter w = new StreamWriter(fs);

    string soapString = (message is SoapServerMessage) ? "SoapResponse" : "SoapRequest";
    w.WriteLine("-----" + soapString + " at " + DateTime.Now);
    w.Flush();
    Copy(newStream, fs);
    w.Close();
    newStream.Position = 0;
    Copy(newStream, oldStream);
}

//public void WriteInput(SoapMessage message)
//{
//    Copy(oldStream, newStream);
//    FileStream fs = new FileStream(filename, FileMode.Append,
//        FileAccess.Write);
//    StreamWriter w = new StreamWriter(fs);

//    string soapString = (message is SoapServerMessage) ?
//        "SoapRequest" : "SoapResponse";
//    w.WriteLine("-----" + soapString +
//        " at " + DateTime.Now);
//    w.Flush();
//    newStream.Position = 0;
//    Copy(newStream, fs);
//    w.Close();
//    newStream.Position = 0;
//}


public void WriteInput(SoapMessage message)
{
    oldStream.Position = 0;
    StreamReader reader = new StreamReader(oldStream);
    StreamWriter writer = new StreamWriter(newStream);
    string data = reader.ReadToEnd();
    data = data.Replace("false", "true");
    writer.Write(data);
    writer.Flush();
}

void Copy(Stream from, Stream to)
{
    TextReader reader = new StreamReader(from);
    TextWriter writer = new StreamWriter(to);
    writer.WriteLine(reader.ReadToEnd());
    writer.Flush();
}
}

它仍然不能正常工作。当服务器上接收到soap请求(WriteInput方法)时,所有“false”值都将更改为“true”,数据将保存到newStream对象,但在webmethod调用中仍将显示“false”值

我的电话是这样的: 客户:

服务器:

 [WebMethod]
    [TraceExtension(Priority = 0)]
    [SoapHeader("Ticket", Direction = SoapHeaderDirection.In)]
    public void SaveNativeRequest(XmlNode nativeRequest, int? batchId)
    {...}
为了完整起见,这是属性类

// Create a SoapExtensionAttribute for the SOAP Extension that can be
// applied to an XML Web service method.
using System;
using System.Web.Services.Protocols;
[AttributeUsage(AttributeTargets.Method)]
public class TraceExtensionAttribute : SoapExtensionAttribute
{
    private string filename = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\log.txt";
    private int priority;

    public override Type ExtensionType
    {
        get { return typeof(TraceExtension); }
    }

    public override int Priority
    {
        get { return priority; }
        set { priority = value; }
    }

    public string Filename
    {
        get
        {
            return filename;
        }
        set
        {
            filename = value;
        }
    }
}
我已经阅读了这篇文章:h**p://hyperlink.net/blog/inside-of-chainstream/,我非常确定我正确地使用了chainstream方法。我知道还有其他方法可以做到这一点,但这似乎真的是一个干净的选择。我读过关于这个主题的各种文章,这篇文章启发了我一个解决方法,我可以使用

(System.Web.HttpContext.Current.Items["RequestSoapContext"] as Microsoft.Web.Services3.SoapContext).Envelope.Body
在ProcessMessage方法中直接操作soap主体(这很好,但很难看)


我是否忽略了一些显而易见的事情?应用程序的其他部分会干扰服务器上的流链接吗?如果有人对此有任何见解,我将非常高兴。

我认为您需要在WriteInput方法中重置newStream的位置

因此,请在WriteInput方法的末尾添加以下行:

newStream.Position = 0;

它应该可以解决您的问题。

我认为您需要在WriteInput方法中重置newStream的位置

因此,请在WriteInput方法的末尾添加以下行:

newStream.Position = 0;

它应该可以解决您的问题。

我对SoapExtensions的第二个建议是,首先开始工作,然后慢慢地将示例转化为您实际需要的SoapExtension。当然,我的第一个建议始终是使用WCF,所以你可以使用比SoapExtension更好的扩展机制。这个应用不是新的,很遗憾,将整个怪物移植到WFC是不可能的。对于你的第二个评论,让这个例子起作用会让整个事情起作用,所以,是的:)@Filip:不,我的意思是,如果你按照指示去做,这个例子确实起作用。让它工作只需要学习如何遵循指示(例如,web.config设置)。然后开始改变它,使之成为你所需要的。我使用扩展来验证传入(和传出!)消息。我一直在发疯,直到我决定回到这个例子。不,它没有。如果提供了方法属性,则不需要编辑web.config。我对SoapExtensions的第二个建议是首先获得工作,然后慢慢地将示例转换为您实际需要的SoapExtension。当然,我的第一个建议始终是使用WCF,所以你可以使用比SoapExtension更好的扩展机制。这个应用不是新的,很遗憾,将整个怪物移植到WFC是不可能的。对于你的第二个评论,让这个例子起作用会让整个事情起作用,所以,是的:)@Filip:不,我的意思是,如果你按照指示去做,这个例子确实起作用。让它工作只需要学习如何遵循指示(例如,web.config设置)。然后开始改变它,使之成为你所需要的。我使用扩展来验证传入(和传出!)消息。我一直在发疯,直到我决定回到这个例子。不,它没有。如果提供了方法属性,则无需编辑web.config。