1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //----------------------------------------------------------------
4 namespace System.ServiceModel.Discovery
5 {
6     using System.Runtime;
7     using System.ServiceModel.Description;
8     using System.ServiceModel.Dispatcher;
9     using System.ServiceModel.Channels;
10 
11     // This behavior sets the contract filter and unhandled operation invoker in the dispatch
12     // runtime to avoid contract filter mismatch exceptions raised by runtime during normal operation.
13     // Since the different discovery messages from different versions are sent over the same multicast
14     // address and port, it is normal for an endpoint to receive the messages that are not matching
15     // its contract. This behavior is only added to UdpDiscoveryEndpoint and UdpAnnouncementEndpoint.
16     class UdpContractFilterBehavior : IEndpointBehavior
17     {
AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)18         public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
19         {
20         }
21 
ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)22         public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
23         {
24             if (clientRuntime != null && clientRuntime.CallbackDispatchRuntime != null && clientRuntime.CallbackDispatchRuntime.UnhandledDispatchOperation != null)
25             {
26                 clientRuntime.CallbackDispatchRuntime.UnhandledDispatchOperation.Invoker = new UnhandledActionOperationInvoker();
27             }
28         }
29 
ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)30         public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
31         {
32             if (endpointDispatcher == null)
33             {
34                 throw FxTrace.Exception.ArgumentNull("endpointDispatcher");
35             }
36 
37             endpointDispatcher.ContractFilter = new MatchAllMessageFilter();
38             endpointDispatcher.DispatchRuntime.UnhandledDispatchOperation.Invoker = new UnhandledActionOperationInvoker();
39         }
40 
Validate(ServiceEndpoint endpoint)41         public void Validate(ServiceEndpoint endpoint)
42         {
43         }
44 
45         class UnhandledActionOperationInvoker : IOperationInvoker
46         {
47             public bool IsSynchronous
48             {
49                 get
50                 {
51                     return true;
52                 }
53             }
54 
AllocateInputs()55             public object[] AllocateInputs()
56             {
57                 return EmptyArray.Allocate(1);
58             }
59 
Invoke(object instance, object[] inputs, out object[] outputs)60             public object Invoke(object instance, object[] inputs, out object[] outputs)
61             {
62                 outputs = EmptyArray.Allocate(0);
63                 return new NullMessage();
64             }
65 
InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)66             public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
67             {
68                 throw FxTrace.Exception.AsError(new NotImplementedException());
69             }
70 
InvokeEnd(object instance, out object[] outputs, IAsyncResult result)71             public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
72             {
73                 throw FxTrace.Exception.AsError(new NotImplementedException());
74             }
75         }
76     }
77 }
78