WCF and Windows Server Service Bus Endpoints - wcf

I need to develop a Windows Server Service Bus topic subscriber (yes, Windows Server and not Azure), and in order to abstract away from the reading, start worker thread, ..., cycle and to take advantage of AppFabric management capabilities, i had the following idea:
Develop a WCF service
Define a Windows Server Service Bus endpoint
And the questions are:
A publisher must use the Service Contract to send messages to the topic?
What should the configuration file look like?
Thanks in advance.

The basic mechanics of how to connect WCF and Service Bus are the same between the Azure and the Server versions. You can use this post as a good starting point:
The main difference between the two is going to be with the endpoint addresses, and how to deal with authentication (since there's no ACS in the server). This post has some useful information on it.
Now, to answer your questions specifically:
A publisher could technically push directly to the service bus queues, but it's better if you use a contract. The problem here is not how to push, but how to build the message in a way that the service can understand it. Having a WCF contract will let you abstract the serialization / deserialization away.
For the configuration, the typical scenario would be to have a WCF service that uses netMessagingBinding. The first post I mentioned has information on the configuration. Just make sure to update the auth and endpoint address pieces to match service bus server's.

To help future related problems here is the required configuration
Extensions required both in publisher and subscriber configuration:
<extensions>
<behaviorExtensions>
<add name="transportClientEndpointBehavior" type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</behaviorExtensions>
<bindingExtensions>
<add name="netMessagingBinding" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingBindingCollectionElement, Microsoft.ServiceBus, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingExtensions>
</extensions>
Note: The Microsoft.ServiceBus assembly is required both in the publisher as well in the subscriber. The package is available in Nuget.
Subscriber side configuration:
<bindings>
<netMessagingBinding>
<binding name="messagingBinding" closeTimeout="00:03:00" openTimeout="00:03:00" receiveTimeout="00:03:00" sendTimeout="00:03:00" sessionIdleTimeout="00:01:00" prefetchCount="-1">
<transportSettings batchFlushInterval="00:00:01" />
</binding>
</netMessagingBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="securityBehavior">
<messageInterceptorBehavior/>
<transportClientEndpointBehavior>
<tokenProvider>
<windowsAuthentication>
<stsUris>
<stsUri value="https://[SERVER]:9355/[NAMESPACE]" />
</stsUris>
</windowsAuthentication>
</tokenProvider>
</transportClientEndpointBehavior>
</behavior>
<endpoint listenUri="sb://[SERVER]/[NAMESPACE]/[TOPIC]/Subscriptions/[SUBSCRIPTIONNAME]"
address="sb://[SERVER]/[NAMESPACE]/[TOPIC]"
behaviorConfiguration="securityBehavior" binding="netMessagingBinding"
bindingConfiguration="messagingBinding" name="InsuranceService"
contract="[WCF_CONTRACT_NAME]" />
Publisher configuration:
<bindings>
<netMessagingBinding>
<binding name="InsuranceService" closeTimeout="00:03:00" openTimeout="00:03:00"
receiveTimeout="00:03:00" sendTimeout="00:03:00" prefetchCount="-1"
sessionIdleTimeout="00:01:00">
<transportSettings batchFlushInterval="00:00:01" />
</binding>
</netMessagingBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="securityBehavior">
<messageInterceptorBehavior/>
<transportClientEndpointBehavior>
<tokenProvider>
<windowsAuthentication>
<stsUris>
<stsUri value="https://[SERVER]:9355/[NAMESPACE]" />
</stsUris>
</windowsAuthentication>
</tokenProvider>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="sb://[SERVER]/[NAMESPACE]/[TOPIC]"
behaviorConfiguration="securityBehavior" binding="netMessagingBinding"
bindingConfiguration="InsuranceService" contract="PushVoucherService.ISubscriber"
name="InsuranceService" />
</client>

Related

How to configure custom behavior on asp.net client consuming wcf restful service

I'm new to WCF Restful services. I have a wcf restful service working as expected. I'm trying to hook custom authentication using request headers. I'm trying to hook message inspectorson both the service and client. The server part works as expected. My question is on the client configuration as the the message inspector BeforeSendRequest method is not invoked. I do not have a reference to restful service. My web.config is asfollows:
<system.serviceModel>
<client>
<endpoint address="http://localhost:8089/RestService" behaviorConfiguration="CustomEndpointBehavior"
binding="webHttpBinding" bindingConfiguration="" contract="WcfRestfulService.IAtlasService"
name="webHttpBinding_IRestService" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="CustomEndpointBehavior">
<ClientAuthenticationMessageInspector />
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="ClientAuthenticationMessageInspector" type="CLientAuthorization.MessageHeaderBehaviorExtention, CLientAuthorization, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
</system.serviceModel>
Am I missing something on this configuration?

WCF Service won't work under HTTPS / SSL

I have a WCF service that I'm using in my Silverlight project. I've followed pretty much any information on how to set up https and ssl for WCF services. The service can be called perfectly fine if SSL in not required but I noticed while examining the communications with fiddler that the WCF service was still in http protocol. Further more if I enable SSL the WCF service cant be browsed in a browser (right clicking in VS2010 -> selecting browse) .
My suspicion is that the service is still being called on some internal method with the http protocol.
Any suggestions to how to fix this?
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
</system.web>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="AuthService.customBinding" >
<binaryMessageEncoding />
<httpsTransport />
</binding>
</customBinding>
</bindings>
<services>
<service name="AuthService">
<endpoint address="" binding="customBinding" bindingConfiguration="AuthService.customBinding" contract="AuthService" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
</configuration>
Thanks
Any specific reason on why you are using a custom binding. Also your service name attribute and contract attribute needs to be fully qualified.
You can use simple basicHttpBinding if you want your WCF service to be compliant with basic profile 1.1 which allows non .NET clients to access as well.

svcutil doesn't generate config file

I have wcf service. I tried to generate proxy code and configuration file for client program by svcutil:
svcutil http://localhost/WcfService2/Files.svc
I got valid file with proxy, but didn't get config file. Why?
(VS2010 SP1, .NET 4.0, IIS 7.0)
My service contract:
[ServiceContract]
public interface IFiles
{
[OperationContract]
Guid UploadFile(Stream stream);
}
My web config:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="WebHttpBinding" maxBufferSize="65536" maxBufferPoolSize="524288"
maxReceivedMessageSize="1073741824" transferMode="Streamed" />
</webHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="MyServiceBehavior" name="WcfService2.Files">
<endpoint behaviorConfiguration="WebHttpBehavior" binding="webHttpBinding"
bindingConfiguration="WebHttpBinding" name="Files" contract="WcfService2.IFiles" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="WebHttpBehavior">
<webHttp defaultBodyStyle="Wrapped" defaultOutgoingResponseFormat="Json"
automaticFormatSelectionEnabled="false" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.web>
<httpRuntime maxRequestLength="100000" />
</system.web>
</configuration>
Endpoints which use the WebHttpBinding (a.k.a., WCF WebHttp endpoints), do not expose metadata like "normal" (i.e., SOAP) endpoints do. WCF will still generate a WSDL for your service (since you specified <serviceMetadata httpGetEnabled="true"/>), but the metadata will only contain certain aspects of the service (such as data contracts, etc). The Web-related features (WebInvoke/WebGet attributes) won't be on the proxy, so even though you get a proxy file, you'll likely won't be able to use it to communicate to the service (unless you didn't use any of those). The problem is that there's no widely accepted format for describing metadata for REST services (WADL is possibly the most used, but it's not nearly as prevalent as WSDL for SOAP, and it's not implemented by WCF).
In short: svcutil doesn't really work for web endpoints.
If you want the long version: http://blogs.msdn.com/b/carlosfigueira/archive/2012/03/26/mixing-add-service-reference-and-wcf-web-http-a-k-a-rest-endpoint-does-not-work.aspx

Two endpoints in WCF 3.5 for SOAP and JSON

I dont know what I am doing wrong. I have a WCF (.NET 3.5) service (JsonSoap.svc) that has two endpoints for soap and json content type. Both the endpoints refer to the same service. I am using only one Json endpoint in the client. My aim is to have the service method GetPerson() to return Json or soap depending on the endpoints used to connect to the service (hopefully this is possible in WCF?). I can see wsdl and was able to successfully ad the service reference in to the client side.
I get the following error after I make a call to the GetPerson() -
"An error occurred while receiving the
HTTP response to
http://localhost:80/JsonSoap/json/GetPerson.
This could be due to the service
endpoint binding not using the HTTP
protocol. This could also be due to
an HTTP request context being aborted
by the server (possibly due to the
service shutting down). See server
logs for more details."
WCF service config
<!-- bindings -->
<bindings>
<basicHttpBinding>
<binding name ="soapBinding">
<security mode="None">
</security>
</binding>
</basicHttpBinding>
<webHttpBinding>
<binding name="webBinding">
</binding>
</webHttpBinding>
</bindings>
<!-- JSON behaviors -->
<endpointBehaviors>
<behavior name="jsonBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="defaultBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="TestService.IJsonSoap" behaviorConfiguration="defaultBehavior">
<host>
<baseAddresses>
<!-- note, choose an available port-->
<add baseAddress="http://localhost:80/JsonSoap" />
</baseAddresses>
</host>
<endpoint address="soap" binding="basicHttpBinding"
bindingConfiguration="soapBinding"
contract="TestService.IJsonSoap" />
<endpoint address="json" binding="webHttpBinding"
bindingConfiguration="webBinding"
behaviorConfiguration="jsonBehavior"
contract="TestService.IJsonSoap" />
</service>
WCF code:
[OperationContract]
[WebGet]
Person GetPerson(int ID);
WCF Client config:
<endpoint address="http://localhost:80/JsonSoap/json" binding="webHttpBinding"
bindingConfiguration="webBinding" behaviorConfiguration="jsonBehavior"
contract="MyService.IJsonSoap" />
Client code:
MyService.JsonSoapClient service = new JsonSoapClient();
MyService.Person person = service.GetPerson(10);
This will not work. WSDL servers only for SOAP services and it is the source for Add Service Reference in Visual Studio. You are using client code generated by Visual Studio but you are using it with Json endpoint which doesn't work.
Json endpoint represents REST service. To call WCF REST service in .NET you must either:
Build manully HTTP Request
Share service contract with a client and use ChannelFactory or WebChannelFactory to build a proxy
Use REST Starter KIT CTP2 and its HttpClient class (not recommended because development of REST Starter KIT ended).

"The caller was not authenticated by the service" when using a customBinding only on machines on a domain

I wrote a WCF service hosted by IIS 6 on a server that is not part of a domain. It uses the following configuration:
<system.serviceModel>
<services>
<service behaviorConfiguration="ServiceBehavior" name="Services.DeliveryStatsService">
<endpoint address="" binding="customBinding" bindingConfiguration="BindingWithMaxClockSkewForIncorrectlyConfiguredWindowsServer"
contract="Services.IDeliveryStatsService" />
</service>
</services>
<bindings>
<customBinding>
<binding name="BindingWithMaxClockSkewForIncorrectlyConfiguredWindowsServer">
<binaryMessageEncoding />
<security>
<localClientSettings maxClockSkew="00:20:00" />
<localServiceSettings maxClockSkew="00:20:00" />
<secureConversationBootstrap />
</security>
<httpTransport />
</binding>
</customBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
It would've been a simple basicHttpBinding, except that the server's clock is not set to the right time and its administrator will not change that, so a customBinding is required to allow for "clockSkew."
Clients use pretty much the same configuration (binding-wise) and can access the service without any trouble, as long as they are not part of a domain. However, clients that are part of a domain are rejected with the message "The caller was not authenticated by the service."
I turned on tracing and it would seem that the problem comes from a token exchange using SSPI negociation. Unfortunately, I can't seem to find the right configuration that will allow both machines that are not part of a domain and machines that are part of a domain to access the service. I have tried several values for authenticationMode, without avail. What's more, as far as I'm concerned, I don't need any particular security on this service.
WCF configuration is far from being my specialty and I haven't found an answer anywhere else, so I hope someone at Stack Overflow will be able to help. Thanks in advance.
Why do you need to set maxClockSkew when you don't need security? It is for handling time differences in timestamps which are not send without security. Once you add security element you turn on authentication because all attributes in the element have default values. Default value for mode is sspiNegotiated. I would start with removing security element.