2011-08-17 88 views
2

我有一个使用.NET Remoting通信的客户端服务器应用程序。出于身份验证的原因,我必须编写自定义IClientChannelSink以将会话cookie插入到HTTP请求中。 在服务器端,我还写了一个自定义IServerChannelSink以从HTTP请求标头中读取服务器需要的一些信息。自定义.NET Remoting IServerChannelSink

的客户端工作正常,但在服务器端,我总是得到以下错误:

System.ArgumentNullException was unhandled by user code Message=No message was deserialized prior to calling the DispatchChannelSink. Parameter name: requestMsg Source=mscorlib ParamName=requestMsg
StackTrace: at System.Runtime.Remoting.Channels.DispatchChannelSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream) at MyAuthentication.MyServerChannelSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream) in C:\Dev\MyAuthentication\MyServerChannelSink.cs:line 82 at System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream) at System.Runtime.Remoting.Channels.Http.HttpServerTransportSink.ServiceRequest(Object state) at System.Runtime.Remoting.Channels.SocketHandler.ProcessRequestNow()
InnerException:

我“的ProcessMessage” -methodlooks如下:如果有人

public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream) 
{ 
    // Pre-processing before sending the message to the next sink in the chain 
    object state = null; 
    ProcessRequest(requestMsg, requestHeaders, ref requestStream, ref state); 

    /* Call the next sink in the chain */ 
    sinkStack.Push(this, state); 
    ServerProcessing serverProcessing = this.NextChannelSink.ProcessMessage(sinkStack, requestMsg, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream); 

    // Processing from sink further in the chain has completed. Now do any post-processing before returning to the previous sink in the chain. 
    ProcessResponse(null, responseHeaders, ref responseStream, state); 

    return serverProcessing; 
} 

将是巨大的可以告诉我什么是错的。

回答

0

我解决了我的问题。由于我不使用通道接收器做任何序列化,我也不想自己处理消息反序列化。下面的FPGA实现正常工作:

public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream) 
{ 
    // Pre-processing before sending the message to the next sink in the chain 
    object state = null; 
    ProcessRequest(requestMsg, requestHeaders, ref requestStream, ref state); 

    ServerProcessing serverProcessing; 
    if (requestMsg != null) 
    { 
     /* Call the next sink in the chain */ 
     sinkStack.Push(this, state); 
     serverProcessing = this.NextChannelSink.ProcessMessage(sinkStack, requestMsg, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream); 
     sinkStack.Pop(this); 
    } 
    else 
    { 
     responseMsg = null; 
     responseHeaders = null; 
     responseStream = null; 
     serverProcessing = ServerProcessing.Complete; 
    } 

    // Processing from sink further in the chain has completed. Now do any post-processing before returning to the previous sink in the chain. 
    ProcessResponse(null, responseHeaders, ref responseStream, state); 

    return serverProcessing; 
} 
2

在某些情况下,requestMsg参数可能是 null。所以你必须处理这些情况。例如,另一个服务器通道接收器 正在调用ProcessMessage函数,并将requestMsg设置为null!

编辑:提供的链接到示例。 以下是服务器接收器示例的链接:Server Sink

+0

你有任何示例代码如何处理这些情况?我找不到Web中IClientChannelSink的任何参考实现。我的IClientChannelSink实现应该只能从HTTP头中读取一些值,但不能以任何方式改变请求消息。 – Alexander

+0

在MSDN中有一个示例实现。但它似乎与我的实现类似http://msdn.microsoft.com/en-us/library/system.runtime.remoting.channels.iserverchannelsink(v=VS.80).aspx – Alexander

0

通过创建服务器频道

TcpServerChannel oTcpChannel = 
    new TcpServerChannel(oTcpChannelConfiguration, oServerSinkProvider, oAuthority); 

您可以设置oServerSinkProvider = null,系统将支持默认接收器提供。您也可以指定您自己的格式化程序,例如TCP通道的soap格式化程序或http通道的二进制格式化程序:SoapServerFormatterSinkProviderBinaryServerFormatterSinkProvider

但是,如果您支持您自己的服务器接收器,则您也必须实现您自己的格式器。

set 
    { 
    if (value != null) 
    { 
     nextProvider = new BinaryServerFormatterSinkProvider(); 
     nextProvider.Next = value; 
    } 
    else 
    { 
     nextProvider = value; 
    }; 
    } 

那么接下来的提供者fomatting,二进制格式的工作在这种情况下:您可以通过在你的函数IServerChannelSinkProvider.Next您设定的部分进行。