[英]WCF ignore duplex in webhttpbinding
Hi i have an service looks something like this. 嗨,我有一项服务看起来像这样。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
public class Service : IService
{
public string test(string value)
{
IServiceCallBack callback = OperationContext.Current.GetCallbackChannel<IServiceCallBack>();
callback.callBackTest("callBack response");
return value + ", normal response";
}
}
[ServiceContract(CallbackContract = typeof(IServiceCallBack))]
public interface IService
{
[OperationContract]
[WebInvoke(
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
Method = "POST")]
string test(string value);
}
public interface IServiceCallBack
{
[OperationContract]
void callBackTest(string value);
}
Now my needs are that two different bindings will use this same service (if possible) i know i can make two entire seperate services for this to work, but i rather not because the two bindings will use the same functions 现在,我的需要是两个不同的绑定将使用同一服务(如果可能),我知道我可以使两个完整的独立服务正常工作,但是我宁可不是因为两个绑定将使用相同的功能
My scenario is that we have some clients which is apple devices that will use an WebHttpBinding
我的情况是,我们有一些客户端,它们是将使用
WebHttpBinding
苹果设备。
And windows clients that will use NetTcpBinding
和将使用
NetTcpBinding
Windows客户端
Now i want the windows clients to be able to use the callback, but with the apple devices i just want to ignore the callback. 现在,我希望Windows客户端能够使用回调,但是对于苹果设备,我只想忽略回调。
if i try to host the service with the WebHttpBinding
i get this error 如果我尝试使用
WebHttpBinding
托管服务, WebHttpBinding
此错误
base = {"Contract requires Duplex,
but Binding 'WebHttpBinding' doesn't
support it or isn't configured properly to support it."}
To me this means that it wont work but can possibly be configured to work? 对我来说,这意味着它将无法正常工作,但可以将其配置为正常工作吗? or do they mean that i have to configure and remove my callback for this to work?
还是他们意味着我必须配置并删除我的回调才能正常工作?
So is it possible to ignore the callback for the WebHttpBinding
and just receive the normal responses? 那么是否可以忽略
WebHttpBinding
的回调而只接收正常响应?
I solved this by editing the endpoint of the webhttpbinding by removing all info about the callback. 我通过删除有关回调的所有信息来编辑webhttpbinding的端点来解决此问题。 so now i have two working endpoints one with callbacks and they can share the same service code.
因此,现在我有两个工作的端点,其中一个具有回调,并且它们可以共享相同的服务代码。
the only downside is that i messed up my mex and i dont know how to solve that one but i made an workaround by not adding the webhttpbinding if you edit your settings that way. 唯一的缺点是我搞砸了mex,但我不知道如何解决这个问题,但如果您以这种方式编辑设置,则不通过添加webhttpbinding来解决问题。
Its not pretty but now i dont have to have two seperate services and duplicate code for all my wcf methods/operations. 它不是很漂亮,但是现在我不必为我的所有wcf方法/操作提供两个单独的服务和重复的代码。
public class WebServiceHost : IDisposable
{
public WebServiceHost()
{
_tcpBaseAddress = "net.tcp://localhost:" + Globals.ClientTcpPort + "/V1";
_httpBaseAddress = "http://localhost:" + Globals.ClientHttpPort + "/V1";
List<Uri> addresses = new List<Uri>() { new Uri(_httpBaseAddress), new Uri(_tcpBaseAddress)};
_host = new System.ServiceModel.Web.WebServiceHost(typeof(Service), addresses.ToArray());
IsOpen = false;
}
readonly System.ServiceModel.Web.WebServiceHost _host;
readonly string _httpBaseAddress;
readonly string _tcpBaseAddress;
public static bool IsOpen { get; set; }
public void OpenHost()
{
try
{
//WebHttpBinding
WebHttpBinding webBinding = new WebHttpBinding();
webBinding.MaxBufferPoolSize = int.MaxValue;
webBinding.MaxReceivedMessageSize = int.MaxValue;
webBinding.Security.Mode = WebHttpSecurityMode.None;
webBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
//NetTcpBinding
NetTcpBinding tcpBinding = new NetTcpBinding();
tcpBinding.MaxBufferPoolSize = int.MaxValue;
tcpBinding.MaxReceivedMessageSize = int.MaxValue;
tcpBinding.Security.Mode = SecurityMode.None;
tcpBinding.Security.Message.ClientCredentialType = MessageCredentialType.None;
//ServiceBehavior
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpsGetEnabled = false;
smb.HttpGetEnabled = true;
_host.Description.Behaviors.Add(smb);
ServiceDebugBehavior sdb = _host.Description.Behaviors.Find<ServiceDebugBehavior>();
sdb.HttpHelpPageEnabled = Globals.IsDebugMode;
sdb.HttpsHelpPageEnabled = Globals.IsDebugMode;
sdb.IncludeExceptionDetailInFaults = Globals.IsDebugMode;
UseRequestHeadersForMetadataAddressBehavior urhfmab = new UseRequestHeadersForMetadataAddressBehavior();
_host.Description.Behaviors.Add(urhfmab);
//MEX endpoint
_host.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName, MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
if (Globals.UseClientTcpHost && Globals.UseClientHttpHost)
{
_host.AddServiceEndpoint(typeof(IService), tcpBinding, _tcpBaseAddress);
_host.AddServiceEndpoint(typeof(IService), webBinding, _httpBaseAddress);
_host.Description.Endpoints[2].Contract = CopyContract(_host.Description.Endpoints[1].Contract);
}
else if (Globals.UseClientTcpHost)
{
_host.AddServiceEndpoint(typeof(IService), tcpBinding, _tcpBaseAddress);
}
else if (Globals.UseClientHttpHost)
{
_host.AddServiceEndpoint(typeof(IService), webBinding, _httpBaseAddress);
_host.Description.Endpoints[1].Contract = CopyContract(_host.Description.Endpoints[1].Contract);
}
_host.Open();
IsOpen = true;
} }
Copy contract method 复制合同方式
private ContractDescription CopyContract(ContractDescription contract)
{
//ContractDescription orgContract = _host.Description.Endpoints[1].Contract;
ContractDescription value = new ContractDescription("IServiceWithCallBack");
//copy the value from orgiginal to the new contract.
foreach (var item in contract.Behaviors)
{
value.Behaviors.Add(item);
}
value.ConfigurationName = contract.ConfigurationName;
value.ContractType = contract.ContractType;
foreach (var item in contract.Operations)
{
OperationDescription operation = new OperationDescription(item.Name, value);
operation.BeginMethod = item.BeginMethod;
foreach (var behavior in item.Behaviors)
{
operation.Behaviors.Add(behavior);
}
operation.EndMethod = item.EndMethod;
foreach (var fault in item.Faults)
{
operation.Faults.Add(fault);
}
operation.IsInitiating = item.IsInitiating;
operation.IsTerminating = item.IsTerminating;
foreach (var knownType in item.KnownTypes)
{
operation.KnownTypes.Add(knownType);
}
foreach (var message in item.Messages)
{
operation.Messages.Add(message);
}
operation.ProtectionLevel = item.ProtectionLevel;
operation.SyncMethod = item.SyncMethod;
value.Operations.Add(operation);
}
value.ProtectionLevel = contract.ProtectionLevel;
value.SessionMode = contract.SessionMode;
List<OperationDescription> removeList = new List<OperationDescription>();
foreach (var item in value.Operations)
{
if (item.Name.ToLower().EndsWith("callback"))
removeList.Add(item);
}
foreach (var item in removeList)
{
value.Operations.Remove(item);
}
return value;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.