I am working on a test project to implement wcf callbacks, my code works when I am debugging locally, the callbacks then actually works, but when ever I connect to the live server it would simply freeze at any methods.
I tried all the Conncurency modes, I tried setting the timeout but it all failed
public interface IWorkplaySupportServiceCallBack
{
[OperationContract(IsOneWay = true)]
void HandleData(byte[] buffer);
[OperationContract(IsOneWay = true)]
void SessionCreated();
}
[ServiceContract(CallbackContract = typeof(IWorkplaySupportServiceCallBack))]
public interface IWorkplaySupportService
{
[OperationContract(IsOneWay = true)]
void CreateSession(string sessionId);
}
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
public class WorkplaySupportService : IWorkplaySupportService
{
public void CreateSession(string sessionId)
{
var callback = OperationContext.Current.GetCallbackChannel<IWorkplaySupportServiceCallBack>();
callback.SessionCreated();
}
}
And here is my configuration
<!-- WCF START-->
<bindings>
<wsDualHttpBinding>
<binding name="basicHttpFor2MBMessage" maxBufferPoolSize="2097152"
maxReceivedMessageSize="2097152" messageEncoding="Mtom">
<readerQuotas maxArrayLength="2097000" />
<security mode="None">
<message clientCredentialType="None" />
</security>
</binding>
</wsDualHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="wsDualHttpBinding.SampleServiceBehavior"
name="Workflowms.Web.webservices.support.WorkplaySupportService">
<endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="basicHttpFor2MBMessage"
contract="Workflowms.Web.webservices.support.IWorkplaySupportService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="wsDualHttpBinding.SampleServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
By use of the Trace events I figured out why it is not responding, but I do not know how to fix this, the Client connecting is my Laptop and the Server is not on the same network (connect Via Internet), I added the wcf reference over the Internet but when I run it I don't get a connection, on the server Trace events I get the following exception
There was no endpoint listening at http://donald-pc/Temporary_Listen_Addresses/f9dbbcde-f968-48f1-bc48-e1e12dd13e32/6ca1305c-95e4-4248-a5f3-cbb594ea8a26 that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
I managed to get it to work without any problem by changing
<endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="basicHttpFor2MBMessage" contract="Workflowms.Web.webservices.support.IWorkplaySupportService"> </endpoint>
To
<endpoint address="" binding="netHttpBinding" bindingConfiguration="netHttpBinding" contract="Workflowms.Web.webservices.support.IWorkplaySupportService">
And Adding
<netHttpBinding>
<binding name="netHttpBinding" maxBufferPoolSize="2097152"
maxReceivedMessageSize="2097152" messageEncoding="Mtom">
<readerQuotas maxArrayLength="2097000" />
<security mode="None">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</netHttpBinding>
Now my callbacks work in Intranet and over Internet
Related
I'm hosting a WCF Service in my WPF app and want to consume it within the same assembly (in another instance, though). For the sake of dependency injection I'm calling ServiceHost.Open with an already created instance of my service implementation.
Contract and Service implementation
[ServiceContract(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
public interface IService
{
[OperationContract]
PartnerInfo GetPartnerInfo();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class Service : IService
{
private IpService _ipService;
public Service(IpService ipService)
{
_ipService = ipService;
}
public PartnerInfo GetPartnerInfo()
{
var info = new PartnerInfo();
info.Address = _ipService.GetLocalIpAddress();
return info;
}
}
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata />
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Project.WebService.Service" behaviorConfiguration="ServiceBehavior">
<endpoint address="endpoint0"
binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IService"
contract="Project.WebService.IService">
<identity>
<servicePrincipalName value="Project.WebService.Service"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:61000/Project/Service.svc" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IService"
transferMode="Buffered"
maxBufferPoolSize="2147483647"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647"
sendTimeout="00:30:00"
receiveTimeout="infinite">
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
</security>
<reliableSession inactivityTimeout="infinite" enabled="true" />
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint
binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IService"
contract="Project.WebService.IService"
name="NetTcpBinding_IService">
</endpoint>
</client>
</system.serviceModel>
</configuration>
ServiceHost creation
_serviceHost = new ServiceHost(_Service);
_serviceHost.Open();
After opening the ServiceHost, it listens on Port 61000 (checked via netstat). Altough I don't need it (because I created a client implementing IService myself), I tested creating a service reference and it worked.
However, my service implementation looks like this:
public class ServiceClient : ClientBase<IService>, IService
{
public ServiceClient(string endpointConfigurationName, EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}
public PartnerInfo GetPartnerInfo()
{
return Channel.GetPartnerInfo();
}
}
And when I'm calling it this way, with another service hosting instance on the same machine, an EndpointNotFoundException is thrown:
Uri baseUri = new Uri("net.tcp://<IPAdress>:61000");
Uri uri = new Uri(baseUri, "Project/Service.svc");
// Spn identity is only here for testing purposes, doesn't work either way
return new ServiceClient("NetTcpBinding_IService", new EndpointAddress(uri, EndpointIdentity.CreateSpnIdentity("NetTcpBinding_IService")));
Am I missing something on my implementation of the ServiceClient as I have both service and client in the same assembly and therefore don't want to create a service reference in Visual Studio?
Update
I tested the whole process creating a Service Reference. This doesn't work either. I also double-checked my firewall rules. Here is the exception message:
There was no endpoint listening at net.tcp://192.168.200.29:61000/Project/Service.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
Update 2
For testing purposes, I created a second wsHttpBinding Endpoint. This one is reachable in my browser, so the service is up and running.
After hours of debugging, I solved the (quite simple) issue myself:
As it turned out, the service URL wasn't net.tcp://localhost:61000/Project/Service.svc but net.tcp://localhost:61000/Project/Service.svc/endpoint0.
After removing the "endpoint0" from my endpoint configuration, the connection went well:
<endpoint address=""
binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IService"
contract="Project.WebService.IService">
<!-- -->
</endpoint>
On my Server, running a Windows Authentication WCF application hosted in IIS 7:
IIS Config: Windows Auth : disabled; anonymous: enabled
<system.serviceModel>
<services>
<service name="Services.AccountService" behaviorConfiguration="MyServiceTypeBehaviors">
<endpoint address="" binding="ws2007HttpBinding" bindingConfiguration="AccountServiceBinding"
contract="Contracts.IAccountService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors" >
<!--<serviceDebug includeExceptionDetailInFaults="true"/>-->
<serviceMetadata httpGetEnabled="true" httpGetUrl="" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<ws2007HttpBinding>
<binding name="AccountServiceBinding" >
<security mode="Message">
<message clientCredentialType="Windows" />
</security>
</binding>
</ws2007HttpBinding>
</bindings>
</system.serviceModel>
and then I create a MVC4 Application with following code to call WCF service:
WS2007HttpBinding myBinding = new WS2007HttpBinding();
myBinding.Security.Mode = SecurityMode.Message;
EndpointAddress endpoint = new EndpointAddress("http://server/accountservice.svc");
AccountServiceClient _client = new AccountServicesObjects.AccountServiceClient(myBinding, endpoint);
_client.ClientCredentials.Windows.ClientCredential.UserName = "username";
_client.ClientCredentials.Windows.ClientCredential.Password = "password";
var user = _client.GetUserInformation(); // works fine
After I finished this mvc4 application, I deploy this website to the Same server which is running WCF one, when I login, occurs:
System.ServiceModel.Security.SecurityNegotiationException: The caller was not authenticated by the service.
System.ServiceModel.FaultException:The request for security token could not be satisfied because authentication failed.
on System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault(Message message, EndpointAddress target)
on System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState)
how this happend?
It seems your service hasn't been started at all. If you enable tracing you can find an exception. There is an error in your configuration - you have no base address, but you have set HttpGetUrl to true (for that option you have to set base address)
This should work for you:
<service name="Services.AccountService" behaviorConfiguration="MyServiceTypeBehaviors">
<endpoint address="accountservice.svc" binding="ws2007HttpBinding"
bindingConfiguration="AccountServiceBinding"
contract="Services.IAccountService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/"/>
</baseAddresses>
</host>
</service>
I'm currently developing a WCF service self hosted in a Windows service with the Self-Hosted SL Svc template.
The template works as it should be and I'm able to make calls from my Silverlight application, but when I tried to modify the project to use Impersonation:
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
It throws me an exception during host.Open();:
System.InvalidOperationException was
unhandled Message=The contract
operation 'GetData' requires Windows
identity for automatic impersonation.
A Windows identity that represents the
caller is not provided by binding
('CustomBinding','http://tempuri.org/')
for contract
('IService1','http://tempuri.org/'.
This is my configuration:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="binaryHttpBinding">
<binaryMessageEncoding/>
<httpTransport/>
</binding>
</customBinding>
</bindings>
<services>
<service name="SLServiceLibrary.Service1" behaviorConfiguration="SLServiceLibrary.ServiceBehavior">
<endpoint address="Service1" binding="customBinding" contract="SLServiceLibrary.IService1" bindingConfiguration="binaryHttpBinding"/>
<endpoint address="" binding="webHttpBinding" contract="SLServiceLibrary.IClientAccessPolicy" behaviorConfiguration="webHttpEnablingBehavior"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="SLServiceLibrary.ServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webHttpEnablingBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
What do I have to change to make this work? do I need to add some configuration to my Silverlight client too?
Thanks in advance :)
I haven't used custom bindings (yet), but this blog entry may give you some help: http://geekswithblogs.net/robz/archive/2007/10/03/wcf-impersonation---specifying-windows-authentication-credentials-on-the-service.aspx
Well after a long search, I've come up with two solutions, one I found at MSDN:
<bindings>
<customBinding>
<binding name="binaryHttpBinding">
<binaryMessageEncoding/>
<httpTransport authenticationScheme="Ntlm"/>
</binding>
</customBinding>
</bindings>
The other one was at the Silverlight forums:
<bindings>
<customBinding>
<binding name="binaryHttpBinding">
<binaryMessageEncoding/>
<httpTransport authenticationScheme="Negotiate"/>
</binding>
</customBinding>
</bindings>
Don't know what is the major difference between these two, I've managed to open the service and call it from Silverlight successfully. If someone call elaborate on the difference, I would appreciate it.
While updating a service reference of my WCF client (simply by clicking Update Service Reference in Visual Studio 2008), following error occurs:
System.ServiceModel.FaultException:
The message with Action
'http://schemas.xmlsoap.org/ws/2004/09/transfer/Get'
cannot be processed at the receiver,
due to a ContractFilter mismatch at
the EndpointDispatcher. This may be
because of either a contract mismatch
(mismatched Actions between sender and
receiver) or a binding/security
mismatch between the sender and the
receiver. Check that sender and
receiver have the same contract and
the same binding (including security
requirements, e.g. Message, Transport,
None). at
System.ServiceModel.Dispatcher.ErrorBehavior.ThrowAndCatch(Exception
e, Message message)
Background:
I've created ErrorServiceBehaviour class. Because such a behavior is created for error handling, IErrorHandler implementation must be applied to each ChannelDispatcher.
public class ErrorServiceBehaviour : Attribute, IServiceBehavior
{
...
public Type FaultType
{
get { return _faultType; }
set { _faultType = value; }
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
dispatcher.ErrorHandlers.Add(new ErrorHandler(_faultType));
}
}
}
public class ErrorHandler : IErrorHandler
{
public ErrorHandler(Type faultType)
{
_faultType = faultType;
}
...
}
Later, I've used that behaviour by applying ErrorServiceBehavior attribute to my service class:
[ErrorServiceBehavior(FaultType = typeof(MyServiceFault))]
public class MyService : IMyService
{
...
}
The thing is, when I comment out the foreach loop inside ApplyDispatchBehavior method, I get no error at all, but that is not the way out (because I want my errors to be handled).
Below there is my service config:
<system.serviceModel>
<services>
<service behaviorConfiguration="DefaultBehavior" name="MyService">
<endpoint address="" binding="wsHttpBinding" contract="IMyService" bindingConfiguration="NoSecurityBinding"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DefaultBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="NoSecurityBinding" >
<security mode="None">
<transport clientCredentialType="None"/>
<message establishSecurityContext="false"/>
</security>
</binding>
<binding name="DefaultBinding" />
</wsHttpBinding>
</bindings>
</system.serviceModel>
Can someone help me?
UPDATE
The code shown earlier:
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
dispatcher.ErrorHandlers.Add(new ErrorHandler(_faultType));
}
adds custom error handling for all endpoints - including the metadata one. But actually this is not the source of the problem - even when I disable adding error handling for metadata endpoint, the issue still occurs.
The other notice is, when I change the bindingConfiguration of the first endpoint to DefaultBinding, I have no error at all:
<services>
<service behaviorConfiguration="DefaultBehavior" name="MyService">
<endpoint address="" binding="wsHttpBinding" contract="IMyService" bindingConfiguration="DefaultBinding"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
Such an option in also not what I want - I still need problematic NoSecurityBinding to work.
Thanks in advance.
Look into the IExtensibleDataObject, it is used to handle different versions of a web service still being able to communicate with each other. This way the contracts don't need to match exactly. Hope this helps.
To begin with, I notice your try to bind a mexHttpBinding to an endpoint although it was never defined inside your "Bindings" tag. This should rise an exception, and I would expect such an exception to look like the one that's bothering you.
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
...
<bindings>
<mexHttpBinding>
THIS TAG WAS MISSING (add security features as needed)
</mexHttpBinding>
<basicHttpBinding>
<binding name="NoSecurityBinding" >
<security mode="None" />
</binding>
<binding name="DefaultBinding" />
</basicHttpBinding>
</bindings>
Also, since you apparently dont need any security feature, you might want to favor basicHttpBinding. As this very thorough answer states, wsHttpBinding really is useful when you want security features.
Your configuration would end up being almost the same, changing "ws" for "basic".
<system.serviceModel>
<services>
<service behaviorConfiguration="DefaultBehavior" name="MyService">
<endpoint address="" binding="basicHttpBinding" contract="IMyService" bindingConfiguration="NoSecurityBinding"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DefaultBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="NoSecurityBinding" >
<security mode="None" />
</binding>
<binding name="DefaultBinding" />
</basicHttpBinding>
</bindings>
Check the App.Config and verify that it is pointing to your deployed Windows service host or set it to point to localhost.
On what you say it seems that your new WCF service do require security and in your NoSecurityBinding you turn it off.
One way to check that is to get WSDL file locally an see if it has: http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd or http://schemas.xmlsoap.org/ws/2004/09/policy or something like that in imports. I'm pretty sure that your updated WCF service has security enabled
Update 1
To get a better vision of your problem you could use WCF Tracing. Here you could see how to turn it on and how to read that traces: "How to turn on WCF tracing"
I don't think you are turning the security completely off. Try this:
<bindings>
<wsHttpBinding>
<binding name="NoSecurityBinding" >
<security mode="None">
<transport clientCredentialType="None"/>
<message clientCredentialType="None"/>
</security>
</binding>
<binding name="DefaultBinding" />
</wsHttpBinding>
</bindings>
Existing web.config setting can create a problem as they are for previous version.
Better to remove existing reference from your WCF client application and Add the reference again.
<services>
<service behaviorConfiguration="ServiceBehaviour" name="Service">
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" contract="IService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
I am attempting to transfer around 7000-8000 objects that are not large (only 9 properties per object instance). Does anyone know why when I begin to retrieve more than 5000 or so objects that I get connection errors? It works perfectly until I hit some threshold for data size.
I am exposing the retrieval of these objects via WCF's TCP service binding. I have the following sample configuration:
<bindings>
<netTcpBinding>
<binding name="NetTcpBindingConfig"
openTimeout="00:01:00"
sendTimeout="00:05:00"
closeTimeout="00:01:00"
maxBufferPoolSize="2147483647"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
<security>
<transport/>
</security>
</binding>
</netTcpBinding>
</bindings>
<services>
<service behaviorConfiguration="ServiceBehavior"
name="TestService">
<endpoint address=""
binding="netTcpBinding"
bindingConfiguration="NetTcpBindingConfig"
contract="ServiceInterfaces.ITestService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8526/TestService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Services.ServiceBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
From my .NET code I am calling the service using a ChannelFactory with the following sample code:
using (ChannelFactory<ITestervice> channel = new ChannelFactory<ITestService>(BindingConfig, "net.tcp://localhost:8526/TestService"))
{
ITestService testService = channel.CreateChannel();
toReturn = testService.LoadAll();
channel.Close();
}
BindingConfig object is a NetTcpBinding property in my code that is populated as 'new NetTcpBinding("NetTcpBindingConfig")'. My client binding is the exact same as my WCF TCP service binding.
Can anyone offer any insight as to how I can retrieve all of the data (it seems my maximum limit is ~5000 objects with my current setup)? Any help is much appreciated. Thanks.
EDIT:
In case anyone runs into this, see the accepted solution about the MaxItemsInObjectGraph. If, however, you are using ChannelFactory from the Client to consume your services, see the following code to make it work:
foreach (OperationDescription operation in channel.Endpoint.Contract.Operations)
{
DataContractSerializerOperationBehavior dataContractBehavior = operation.Behaviors[typeof(DataContractSerializerOperationBehavior)] as DataContractSerializerOperationBehavior;
if (dataContractBehavior != null)
dataContractBehavior.MaxItemsInObjectGraph = int.MaxValue;
}
Consider increasing MaxItemsInObjectGraph quota as well (its default value is 64k). It should be on both the server and the client side. See the sample configuration: