之前调试Remoting程序时有碰到“指定的 SOAPAction 无效”的问题,即客户端调用远程remoting方法时,提示SOAPAction 无效,一时不知道怎么解决。在网上百度下,看到一篇文章“Remoting在HttpChannel下抛“指定的 SOAPAction 无效”异常的解决办法 ”, 按照该文章的说法,只需要把客户端的程序集名称和命名空间改成与服务端的一样就可以了。
按照文章提到这种做法,试了下,果然可以调用。不过问题来了,如果都这样的话,调用客户一多,难不成客户端都要改成一样的程序集名一样的命名空间?其实这样的方法是治标不治本,没有找到问题真正所在。 我仔细看下了remoting服务端生成的soap(rem)格式的xml服务文件,里面方法节点对应的namespace和SoapAction都是根据程序集名称和命名空间组成,类似"soapAction="http://schemas.microsoft.com/clr/nsassem/TestShrek.RemoteObject/TomLib#get_StartTime" ,其中 TestShrek.RemoteObject是类名(带命名空间), TomLib是程序集名称,get_StartTime的StartTime(属性)是调用的方法名。 而在客户端调用时也是按照客户端程序集和命名空间以及方法来调用。这样一来客户端和服务端生成调用就可能不一样了。
解决的办法其实很简单的,就是给相应的服务方法(上面提到的StartTime)加上SoapMethod特性,并指定NameSpace和SoapAction。这个指定必须在服务端和客户端的服务类(接口)中同时指定,而且要一样。如下:
interface iRemoteObject //客户端
{
int Count();
int Add(int i);
DateTime StartTime { get; }
string Status { get; }
string IsProcessing { get; }
[SoapMethod(XmlNamespace = "TomasX", SoapAction = "TomasX#Greeting")]
string Greeting(string name);
}
服务端
[SoapMethod(XmlNamespace = "TomasX", SoapAction = "TomasX#Greeting")]
public string Greeting(string name)
{
GYF.WriteLog(name+"\t test", "");
return "Hello," + name;
}