Specify default WCF endpoint in app.config - wcf

When you add a service reference it creates the class "MyServiceClient" with a default constructor. If I use new MyServiceClient() I get an error: Could not find default endpoint... If I use new MyServiceClient("endpointName") it works.
I would like to specify a default endpoint in app/web.config which will get used when I use the default constructor. I know I can place that default name in *.settings and use it throughout my app, but just wondering if there is any built-in way to do it.

If you have only a single endpoint in your client's app.config, then that one endpoint will be used.
If yuo have multiple endpoints in your client's app.config, you must define which one to use. There's no mechanism or feature in WCF do designate one as the "default" endpoint - and I haven't heard anything about WCF 4 adding any such feature, either.
So if you want to have a default endpoint, then yes, you'll have to store the name of the endpoint in your app.config as well and programmatically retrieve that name before instantiating the endpoint.

Related

How to reference the WCF service by code-behind in UWP?

Now I need to reference a WCF service in a UWP program. However, the address of the WCF service may change frequently in the future.
I don't want to rebuild/republish the project every time when the address change.
So I want to use a LocalSettings to Save/Load the address of WCF service. Every the program begins, it will reload the address from the LocalSettings. And if the address changes, I just only let the customer change the LocalSettings from UI but not need to rebuild/republish the project.
How can I do it? Or there is any other better to do it?
If it's a RESTful service, you could use HttpClient relevant APIs to consume a REST service in UWP.
Please note that REST is a resource that implements a uniform interface using standard HTTP GET, POST, PUT methods that can be located by URI. So, you could use HttpClient to call it in code-behind. You will get response after you send http request, then you could analysis the response result.
The similar thread for your reference: Calling web service asynchronously in page constructor.
Using LocalSettings for such thing is a good solution.
LocalSettings are just a dictionary where you can assign values you want to store and later take out.
ApplicationData.Current.LocalSettings["ServiceAddress"] = "something";
Debug.WriteLine(ApplicationData.Current.LocalSettings["ServiceAddress"]);
Such setting will survive app restart and is stored in applicaton's private storage.
You will probably want to seed this setting with a default value at first startup.

Invoke WCF Workflow Service using different endpoint addresses

I created a Workflow Foundation workflow which will eventually invoke another Workflow Service. I added the call to this service by dragging the appropriate shape from the toolbox onto the designer. The shape was available because I added the Workflow Service as a service reference as recommended.
How can I specify a specific endpoint address for this web service? I can't find a way to programmatically specify the address.
The workflow always uses the address specified in the web.config. But based on certain conditions I want to use different addresses.
Edit
Here is a picture I created to illustrate the problem:
Look for the place where you make a call to the Workflow Service. Somewhere there you define a client. It should look something like this:
client.InvokeService(); // or whatever method you call;
If you want to change address you should change endpoint address before this call, ideally when you define the client:
client.ChannelFactory.Endpoint.Address = new EndpointAddress("http://something.com/service.wsdl");
But keep in mind that this is not recommended practice. If you intend to change it programmatically it's better to get rid of services section in your web.config completely and set properties programmatically when creating client.

WCF: Do I Need to replace "http://tempuri.org/" with a dynamic namespace?

I have a web service that will be deployed to multiple domains. I would like to get rid of the WCF default namespace of "http://tempuri.org/," and replace it with the domain on which the web service is deployed, such as "http://mydomain.com/." I know the best solution here is simply to have the web service exist in one place, and use that one domain as the namespace, but that is not an option for me at the moment.
I found a partial answer to this question here. In this post, the suggested answer is to set a URL property in the config file, but I am afraid I don't quite understand the answer. Where is this URL property, exactly? Also, for reasons beyond my control, the client app that will be consuming this web service does not have an app.config file, so all configs in that client app will have to be set in code. I am not sure if that matters, but figured I would mention it, just in case.
EDIT: To clarify, the reference to "http://tempuri.org" that I am trying to remove is inside the .cs file that is generated by svcutil.exe.
e.g.
[System.ServiceModel.OperationContractAttribute(Action = "http://tempuri.org/IEmailService/SendEmail", ReplyAction = "http://tempuri.org/IEmailService/SendEmailResponse")]
void SendEmail(Services.Internal.CorrespondenceWebService.Email email);
You may be confusing XML namespaces with URLs. Here's an example of a namespace which is not a URL: urn:schemas-microsoft-com:datatypes.
Since a namespace is not necessarily a URL, you do not have to change it for each environment.
On the other hand, you should pick a namespace, and use it consistently. Perhaps something like http://services.mydepartment.mycompany.com/myservice/. You really don't want to ship a service that still uses http://tempuri.org/, as that demonstrates a lack of understanding of namespaces.
In response to your updated question: those namespaces are present in the .cs file generated by svcutil.exe because they are present in the metadata from the service. You need to change them in the service, and when the client is created or updated, it will have the correct namespaces.

WCF: parameters handled in custom channel not present in generated WSDL

I have some special parameters to all my wcf service methods that are handled inside a custom channel and are not exposed in the service method parameter list. This works fine for json/xml endpoints, but the I don't know how to use a SOAP endpoint with this setup because the generated WSDL doesn't include fields that are not in the service call parameter list.
Is there a way I can centralize the handling of the special parameters that apply to all service methods (authentication, locale and other contextual information) and provide a SOAP endpoint that Just Works (tm)?
Hand editing wsdl files is not an option.
Provide something that implements IWsdlExportExtension to modify the WSDL as it is generated to contain the extra information you want. (Your custom channel BindingElement might be a good place to do this).

Programmatically and globally adding a custom WCF client endpoint behavior extension

I have the need to add a custom behavior extension to my WCF client endpoints. I tried doing this through configuration, but have been bitten by the often-mentioned bug where WFC configuration can't parse the type name correctly. So can I do this programatically instead?
I can't modify the configuration sections at runtime because they are read-only. I know if I get ahold of an instance of a client proxy (i.e. ClientBase), I can add to its Endpoint.Behaviors an instance of my custom behavior. However, I would have to do this for each instance.
Can I get to the endpoints globally and pre-add them (e.g. in Global.asax), or are these endpoints instantiated and discarded transiently?
You should be able to add the behavior to the client in code something like this:
IMyEndpointBehavior behavior = client.Endpoint.Behaviors.Find<IMyEndpointBehavior>();
if(behavior == null)
{
client.Endpoint.Behaviors.Add(new MyEndpointBehaviorImplementation());
}
The first line would check if that behavior has already been applied to avoid applying it twice. If it's not been applied already (the .Find() call returns null), then you can programmatically add that behavior to your client class.
You need to do all this before issuing the first call to the service, obviously. Once you've done that, you cannot change the client anymore.
Marc