Changing a WCF service from WSDualHHTP to NETTCP error - c#

I have a WCF service set up as a WSDuallHTTP and everything works ok using this. The problem I have is that I need to be able to get the service to run as a non admin program. I know I can setup the WCF service so that an admin just has to grant right for the service to be able to run on a certain port range but If I can get rid of the need for admins altogether it would be much better.
Due to this I have read that the NETTCP binding both supports duplex and doesnt require admin rights to host the service. My first question is is this correct?
Also when I change the WSDualHTTP binding to a NETTCP binding I get the following error.
Could not find a base address that matches scheme net.tcp for the endpoint with binding NetTcpBinding. Registered base address schemes are [http].
Here is the code thats failing:
string WCFHost = string.Format(WCF_URL, MainConfiguration.WCFCommunicationsURL,
MainConfiguration.WCFCommunicationsPort);
this.serviceHost = new ServiceHost(typeof(GX3WCFServerService), new Uri(WCFHost));
NetTcpBinding binding = new NetTcpBinding();
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
this.serviceHost.AddServiceEndpoint(typeof(IGX3WCFServerService), binding, "");
//the line above it the one throwing the exception
Please let me know if you need anymore information.

Worked out what the problem was. my WCFHost string began with HTTP:\ instead of NET.TCP:\

Related

C# SoapHttpClientProtocol - set local binding address (source address)

I am trying to make a Soap call to a webservice hosted by business partner. The problem I am having is that our client is hosted on a virtual PC with multiple IPs. I would like to call the hosted webservice with a different (not default) IP address. Why is that? There is VPN connection between our client application and hosted webservice but it is set up LAN2LAN between two IPs. Now I have to change local source IP address to match with the VPN requirements.
I have tried using SoapHttpClientProtocol's WebProxy, setting its value to the new IP but it does not seem to work. I am getting HTTP 404 error.
Here is some of the code:
//soapApiClient is typeof SoapHttpClientProtocol
//endpoint url -> webservice, url from appSettings
var url = SettingsProvider.ClientSapGetUserDataUrl;
soapApiClient.Url = url;
//proxy settings -> setting new IP, defined in appSettings
var proxy = SettingsProvider.ClientProxyAddress;
soapApiClient.Proxy = new WebProxy(proxy);
//credentials
soapApiClient.Credentials = GetCredentials();
I HTTP post user code and return value should be user data from SAP, currently I am getting 404 http error code. For comparison, it works like a charm from SoapUI. Maybe setting proxy is not what I am looking for? Any help would be much appreciated.
EDIT: To be more clear
Currently, by default service is called from default ip 91.185.201.88. Service's IP is 10.67.145.70. I want to change it like so: service is called from 192.168.4.2 to service's 10.67.145.70.
I finally managed to make it work. If anyone else will have problem with this, just follow these instructions.
Before calling remote service, you have to find service point for it. This is done via ServicePointManager like so
Example:
var servicePointUserReader = ServicePointManager.FindServicePoint(new Uri(FULLY QUALIFIED REMOTE SERVICE URL));
servicePointUserReader.BindIPEndPointDelegate = (sp, remote, retryCount) => new IPEndPoint(IPAddress.Parse(SOURCE IP FROM WHICH YOU WANT TO SEND REQUEST), 0);
In my example, fully qualified remote service url was something like http://65.145.63.71:8010/sapService (this is the one we are trying to call). Then I wanted to make a call from a different IP on our virtual PC which has many IPs addressed to it. You just need to input desired IP as shown in the second line of the code, for example 192.168.5.1.
Make sure you use "http://" when calling FindServicePoint with new Uri() constrcutor otherwise it will not work!
After that just proceed with the call to the service. Two lines of code, that's all you need. :)

Dynamically consuming WCF in Windows Phone 8 App

I have a WP8 app and this app needs to consume a WCF service to send/receive data from my server.
I have the service and the app working well in my developer computer, using localhost and VS2013.
Now I installed the WCF service in IIS and the service is working well!
My question is: I want a way to dinamicaly change the address of my WCF service without the need to recompile the app and deploy it!
I've found this peace of code in another thread at SO that I would like to know if it would work in any address that I change in my app dinamycally:
private MyServiceClient GetMyServiceClient(string url)
{
Uri uri = new Uri(url);
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
EndpointAddress address = new EndpointAddress(uri);
MyServiceClient client = new MyServiceClient(binding, address);
return client;
}
My app will run for now just in intranet enviroment, so I don't need a high security level to access my server, the basic httpbinding it's for now good enough.
You can look at putting your wcf configuration into a configuration file. See the post here - http://msdn.microsoft.com/en-us/library/ms733932(v=vs.110).aspx
Also take a look at this link - http://www.codeproject.com/Articles/576820/Basic-Step-by-Step-WCF-WebService
It gives an example of consuming a wcf endpoint that is defined in a config file. It uses a wpf example, but it should be easily adaptable to your scenario.

Programmatically Changing the Default Collection for WCF Proxy Class

I have an application where users will connect to one or more WCF services running on machines in their network. Because the address of these connections are not known at the time of installation, the application must programmatically connect to these services (i.e. I cannot use Add Service Reference). I have the connection working using the following code:
string url = "...the url...";
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress address = new EndpointAddress(url);
ILicenseService service = ChannelFactory<ILicenseService>.CreateChannel(binding, address);
However, some of the members of my service class return an ObservableCollection of elements. I know how to change the collection type in the Service Reference dialog box, using Advanced settings. However, I cannot figure out a way to set this value programatically so that my client knows to read the return type as an ObservableCollection instead of a List. Any clues?
It should deserialize to the type which is defined by the interface of the service class, or to the type of the property of the serialized object. Try just changing the collection type on the interface/class.
By the way, you stated that you cannot use Add service reference because the service endpoint address is not known at compile time, but that shouldn't stop you from using it. Obtain a copy of the WSDL and import it in Add service reference from local WSDL file, then when creating a service proxy specify the actual endpoint address as shown here.

Using WCF service in MonoTouch with Authentication

I am using a WCF service client generated by slsvcutil form Silverlight toolkit version 4. I've also tried version 3 with the same problems. When I use a client instance running on http with no user credentials it runs without problems. But I need to switch to https for productive servers and send user credentials that are hardcoded for my application. I use the following code for that:
var binding = new BasicHttpBinding (BasicHttpSecurityMode.TransportCredentialOnly);
var endpoint = new EndpointAddress (AppSettings.FlareEndPoint);
_service = new TopicAnalystAPIClient(binding, endpoint);
_service.ClientCredentials.UserName.UserName = "xxx";
_service.ClientCredentials.UserName.Password = "xxx";
When I call a method on that service pointing to http with no authentication it works. When I use the this code against http/https with the credential I get "There was an error on processing web request: Status code 401(Unauthorized): Unauthorized" exception. I've checked that the credentials are correct, I am able to open the service reference in my browser. I've also tried several combinations of http/https and SecurityMode value. I've also tried it on four different servers always with the same result.
What can be the problem?
A lot of permutations are possible. BasicHttpSecurityMode.TransportCredentialOnly should be usable without SSL [1] using HTTP itself. This means the server will send one (or more) authentication method(s) to the client (e.g. basic, digest, ntlm) and Mono (including MonoTouch) should be providing support for the most of them.
It is possible that the linker (if used) removes one of them. In that case you could try building and testing without linking (or skip linking of System.Net.dll).
It's also possible that the authentication method that the serve insist on is not supported. You could find which one is used by running a network trace (e.g. wireshark) or, maybe, it will show up in more details in the server log (along with the 401 error).
[1] http://msdn.microsoft.com/en-us/library/system.servicemodel.basichttpsecuritymode%28v=vs.95%29.aspx

WCF: Client Impersonation

I have a console app client that talks to a WCF service hosted by a console app on a different server. It use windows authentication with security mode = message
It works just fine until I change the service to impersonate the clients credentials. The changes I do to accomplish that is:
1. Add <serviceAuthorization impersonateCallerForAllOperations="true" /> to the service behaviour
2. Add [OperationBehavior(Impersonation = ImpersonationOption.Required)] to my method signature
I then host my service and it runs as normal, all good.
In my client the only thing I do is add:
ChannelFactory<IService1> channel = new ChannelFactory<IService1>(binding, endPoint);
channel.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
I then run my client and get the error:
The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
Is there something else I'm missing that I need to do to the client config?
It could be that your server settings do not match the contract.
On the server side:
Is IIS set to windows authentication?
Is web.config set to windows authentication?
Is web.config set to impersonate = true
My guess is that you are missing the last one.
I would suspect that the wcf method call triggers an exception on the server side. Do you have any infrastructure in place to capture server side exceptions or payloads? If not then use something like wcf trace logging to record traffic.
This should give you a more meaningful error.
If you can add this to your question hopefully we can discern what is causing the issue.

Categories