Azure Slot Swapping: Configure WCF endpoint in Azure - c#

I want to use Slot Swapping on Azure for a WCF Service. I know that we can do the appSettings directly in Azure. I couldn't find an option to configure the system.serviceModel/client, but for slot swapping i need 3 endpoint configurations, one on each slot I have
<system.serviceModel>
<client>
<endpoint address="http://myservice-devslot.azurewebsites.net/ServiceName.svc" ... />
</client>
This would be the configuration for 1 slot, as it's shown in the address: dev-slot
Or is there an other approach to manage endpoints?

Ok, I configured the endpoint address through Code and added an EndPointAddress Key to the AppSettings. Now I can swap from TEST to INT etc by just do one click in Azure. Thanks everyone
wcfServiceClient.Endpoint.Address = new EndpointAddress(endPointAddress);

For editing config files depending on the destination environment you're going to deploy the application to, you'd usually use config transformations.
As you're looking to so using azure, have a look at this article by Brady Gaster as starting point. It describes the whole procedure quite detailed.

Related

WCF: Is configuration in App.config better than in hard-coded in custom Proxy class?

first of all this is not duplicate. I have a little bit different question.
Is it good practice to get rid of WCF's config in App.config file in the client (or clients in case of cross-platform project) and replace it with injected Proxy class (from different dll, shared for all clients)?
I'm just starting so my config file is not big, but here is an example:
App.config (WCF part):
<system.serviceModel>
<client>
<endpoint address="net.tcp://localhost:8002/MyService"
binding="netTcpBinding"
contract="CallbackExample.Client.IMyService" />
</client>
</system.serviceModel>
I must have this code copy and pasted into every client I made. Working with Xamarin I can have many clients written in C# in single VS solution. So I though, why not just get rid of system.serviceModel section and do that:
MyServiceProxy.cs:
public class MyServiceProxy : ClientBase<IMyService>, IMyService
{
public MyServiceProxy()
: base(new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:8002/MyService"))
{
}
public int JustAMethod()
{
return Channel.JustAMethod();
}
}
This way, I will have my configuration in single place.
So, my question is: Is it considered as a good practice? Is there a better way? I'm not sure, cause WCF is all about flexibility and easy config through App.config flie.
If there is no need for additional configuration, I always go for pure code solutions.
Back in the day WCF was slightly more complex to configure, via app.conf. With the ServiceHost you can even configure a WCF service in pure code.
The same applies to a WCF client imo; if you don't have the need to configure it via a config file for your users: I'd say go for the pure code solution.
Here another discussion of the same topic. (kind of the same reasoning, the question remains; do you need the configuration flexibility).
One potential downside to doing everything in code is that you lose the flexibility to configure not just the endpoint, but also the binding, without recompiling and redeploying. The binding includes some important network-related attributes (timeouts, transport protection levels, authorization schemes, etc) that you may want to tweak depending on the environment in which some of your client programs can run.
Note that you don't necessarily have to have a separate *.exe.config file for every client application. You can have a common .config file that each application can load explicitly. See ConfigurationManager.OpenMappedExeConfiguration

How to control NServiceBus queue name when hosted on Azure?

For some reason the queue hosted on windows azure is not respecting the .DefineEndpointName() configuration.
The queue name on Azure Bus is always named after the worker role that's hosting it. While this is fine, in general, I'd feel a lot better if there was an option to manually override the convention.
How can I define my own queue name?
There is a configuration setting that can be used to control the queue name:
You can add it to your service configuration files like this,
<Setting name="AzureQueueConfig.QueueName" value="yourqueue" />
Or add it in app.config like this:
<AzureQueueConfig QueueName="yourqueue" />
PS: Define endpoint name should work as well, can you reproduce the issue in a small sample and file it as an issue on https://github.com/nservicebus/nservicebus
Thanks,
Yves

Getting Error "This collection already contains an address with scheme http" with WCF on local machine

I'm trying out WCF for the first time and getting the following error when I try to instantiate the host:
This collection already contains an address with scheme http...
I have found a lot of other references to this and tried some of the solution to no avail. One fairly common thread that does not apply to me is that the problem is on a web server of some sort. I'm just running everything from my local machine.
One interesting symptom I found is that I'm developing a c# Forms app. Originally my top level form object inherited my service interface instead of a separate Service class. When I implement this way, there is no error on the host side but I have been having trouble on the client side.
Based on this solution:
How to solve "The ChannelDispatcher is unable to open its IChannelListener" error?
...I decided to separate the service host into a separate object. That's when I start seeing the problem.
The ServiceContract is simple enough:
[ServiceContract]
public interface ISSAService
{
[OperationContract]
void CreateSpaMonitor();
}
I instantiate the service like this:
Uri baseAddr = new Uri("http://localhost:8000/SSAService");
ServiceHost localHost = new ServiceHost(typeof(SSAService), baseAddr);
Where SSAService is the implementation of the Service interface.
If I change the second line to the following (and implement the interface...) the error goes away:
Uri baseAddr = new Uri("http://localhost:8000/SSAService");
ServiceHost localHost = new ServiceHost(typeof(SSAManager), baseAddr);
Where SSAManager is my top level Forms class...
Then I run into a client side problem which is where I started....
I have tried changing the port number and that doesn't seem to affect anything.
I'm new to WCF so maybe I'm missing something obvious.
Thanks.
I was getting this error:
This collection already contains an address with scheme https. There can be at most one address per scheme in this collection. If your service is being hosted in IIS you can fix the problem by setting 'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled' to true or specifying 'system.serviceModel/serviceHostingEnvironment/baseAddressPrefixFilters'.
Parameter name: item
I resolved it by doing the following to my web.config. Perhaps something changed in the .NET Framework 4 which is requiring this line, since I didn't need it before:
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<!-- Rest of the system.serviceModel content omitted for brevity--->
<system.serviceModel>
This can also occur if you have multiple bindings on the same IIS site with different domain names/ports. I resolved the issue by removing the extra named binding.
One of the solution I found previously was to add something like this:
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="http://localhost:8000"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
And then specifying the endpoint address absolutely. This didn't seem to have an effect but I was still using baseAddr in the constructor as shown above.
The solution for me was to remove baseAddr from the constructor.

Sending a "larger" collection of data to an Azure WCF Service

I'm trying to create a web service using Azure.
For the time being, everything is being run locally. The web service and Azure work fine, a simple string Test() method which returns "Hello world" works without problems, as you'd expect. ;)
Now, I've created two methods which add rows to Azure Data Tables. The first sends (using a special DataContract) a single row of data, and this works fine.
The second is for sending larger amount of data, and sends an IEnumerable. So, to test the service, I've created a client application which creates a number of random data to send. If I create up to 42 rows and send that, all goes well.
Above that, I get a 400 Bad request error.
The problem is that there's no inner message to work with (or rather, that WAS the inner message). I strongly suspect it has to do with the size of the request however.
Note, that if I put a breakpoint on the service's method, it doesn't even get that far. I've read quite a few various forum posts regarding similar issues, but those seemed to deal with ordinary WCF services, not Azure ones, and so the Web.config file doesn't contain definitions for bindings nor endpoints, which would be something I could work with.
Please help.
PS. I realise I may have posted very little information. If something else is needed, please ask, and I'll do my best to include it.
Adding the following lines to the Web.config file (under system.serviceModel) in the Azure service project (NOT the Web.config in the client application) resolved the issue:
<bindings>
<basicHttpBinding>
<!--The basicHttpBinding is used for clients which use the generated code to transmit data; the following
settings make it possible to send larger amounts to the service-->
<binding maxReceivedMessageSize="10000000" receiveTimeout="01:00:00">
<readerQuotas maxStringContentLength="10000000" />
</binding>
</basicHttpBinding>
</bindings>

Managing multiple WCF endpoints for the same service

I am building an single application that uses WCF to call out to multiple external endpoints. All of the remote endpoints are identical except for the URI. I would like to treat them as a pool: add and remove endpoints through configuration and have the application understand what to do.
My original plan was to define one endoint in the app.config, then iterate over my list of endpoints and update client.Endpoint.Address on the fly to point to the right place. Unfortunately, that property is read-only, rendering that plan unworkable.
I'm a little bit stumped here. Any suggestions on how I might accomplish this?
How to: Create a Service Endpoint in Code shows you how to manage service endpoints in code rather than configuration.
Have you tried a separate name that is passed in to the client constructor?
<endpoint address="http://localhost:18000/MyService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyService"
contract="MyServiceReference.IMyService" name="BasicHttpBinding_IMyService" />
<endpoint address="http://localhost:18001/MyService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyService"
contract="MyServiceReference.IMyService" name="MyService_Secondary" />
<endpoint address="http://localhost:18002/MyService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyService"
contract="MyServiceReference.IMyService" name="MyService_Tertiary" />
Store the end point addresses in a DB table and use Jason's suggestion for creating end points in code. When a new endpoint shows up you just add another row to the table and force the service to re-query the endpoint table.
How to: Create a Service Endpoint in Code
http://msdn.microsoft.com/en-us/library/ms731080.aspx

Categories

Resources