我正在尝试创建一个接受接口的wcf服务,并在客户端调用其他wcf函数时激活它。 Wcf服务接口:
[ServiceContract]
public interface IAction
{
[OperationContract]
void OnIndexChanged(int index);
}
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IService1
{
[OperationContract]
void Add(int iCount);
[OperationContract]
void Subtract(int iCount);
[OperationContract]
void Subscribe(IAction action);
// TODO: Add your service operations here
}
WCF服务实施:
public class Service1 : IService1
{
static int index = 0;
static IAction act = null;
public void Add(int iCount)
{
index += iCount;
act?.OnIndexChanged(index);
}
public void Subscribe(IAction action)
{
act = action;
}
public void Subtract(int iCount)
{
index -= iCount;
act?.OnIndexChanged(index);
}
}
客户:
public class TestAction : IAction
{
public int Index { get; set; }
public void Run()
{
Index = 0;
WCF.IService1 service = new WCF.Service1Client();
try
{
service.Subscribe(this);
service.Add(3);
service.Subtract(2);
service.Add(1);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public void OnIndexChanged(int index)
{
Index = index;
Console.WriteLine("On_Changed_Index is - > " + index);
}
}
主要:
class Program
{
static void Main(string[] args)
{
TestAction ts = new TestAction();
ts.Run();
Console.Read();
}
}
然而它不起作用。它表示存在类型序列化异常,如下所示:
There was an error while trying to serialize parameter http://tempuri.org/:action. The InnerException message was 'Type 'Tester.TestAction' with data contract name 'TestAction:http://schemas.datacontract.org/2004/07/Tester' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.'. Please see InnerException for more details.
有谁知道为什么会这样?我不想给出一个特定的名称,因为每个客户端在不同的项目中都有不同的Implemantation,所以我不能在TestAction类中指定类型的类型。
答案 0 :(得分:0)
它无效。基本上,当WCF运行时接收请求时,根据SOAP中存在的Action(您从客户端调用的方法),使用反射它会创建一个服务实例,并将在该实例上调用该Action。此外,在此过程中,它将通过反序列化根据数据协定在SOAP数据包中发送的参数将参数传递给该操作。话虽如此,这意味着所有这一切都发生在不同的应用领域(事实上是过程)和通常的OOP概念实时超载,覆盖赢得了你想象的工作。在您的示例中,当您使用SOAP与另一个进程/计算机中的某些对象进行通信时,服务对TestAction
一无所知。合理 ?
答案 1 :(得分:0)
您正在尝试通过事件实现回调,但WCF有一个内置方法来支持此功能。
由于 IAction 是您的回调方法,因此无需使用服务合约进行装饰。
public interface IAction
{
[OperationContract(IsOneWay = true)]
void OnIndexChanged(int index);
}
通知合同 IService1 您有回调关联。
[ServiceContract(CallbackContract = typeof(IAction))] [服务合约] 公共接口IService1 {
[OperationContract]
void Add(int iCount);
[OperationContract]
void Subtract(int iCount);
}
现在您可以决定何时调用您的回调方法。
public void Add(int iCount)
{
index += iCount;
OperationContext.Current.GetCallbackChannel<IAction>().OnIndexChanged(index);
}
同样对于减法方法也是如此。
现在,如果你想调用回调,你需要通过在主类的方法中实现来调用回调的接口方法。
[CallbackBehavior(UseSynchronizationContext = false)]
class MyClass:FullNameSpace.IAction
{
public void MainMethod()
{
InstanceContext instanceContext = new InstanceContext(this);
mynamespace.Service1 client = new
//your add and subtract method can be accessed by client.
}
public void OnIndexChanged(int index)
{
string result= = index.ToString() ;
}
}