WCF: Cant get my Web service to work, on the server - c#

My issue is that i have this Webservice EService that works really great in my debug projekt, but when i implement it into a WinForm projekt, and put the service on a server. I get this error when crateing the client?
An unhandled exception of type 'System.InvalidOperationException'
occurred in System.ServiceModel.dll
Could not find default endpoint element that references contract '{0}' in the ServiceModel
client configuration section. This might be because no configuration file was found for your application,
or because no endpoint element matching this contract could be found in the client element.
App.config
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IEService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://Domane.dk/EService.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IEService" contract="IEService"
name="BasicHttpBinding_IEService" />
</client>
Web.config
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpBinding" scheme="http" />
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<bindings>
<basicHttpBinding>
<binding name="" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
The way im calling it
using (var test = new EServiceAPI.EServiceClient())
{
test.OpdaterLeastDatoWinPLC(connstr);
}
I cant se the reason why it fails. Sorry for being such a newbi. And yes i've harvestet the internet for 2 days trying to find a solusion now.

I have had the same problem when using a web service in a dll.
Try this:
using (var test = CreateWebServiceInstance("http://url.to.mywebservice.com"))
{
test.OpdaterLeastDatoWinPLC(connstr);
}
Enter the correct url to the web service above and create the client using the code below. You still need to add the web service to the project so that the class EServiceClient is created for you.
internal static EServiceAPI.EServiceClient CreateWebServiceInstance(string url) {
BasicHttpBinding binding = new BasicHttpBinding();
binding.SendTimeout = TimeSpan.FromMinutes(10);
binding.OpenTimeout = TimeSpan.FromMinutes(1);
binding.CloseTimeout = TimeSpan.FromMinutes(1);
binding.ReceiveTimeout = TimeSpan.FromMinutes(20);
binding.AllowCookies = false;
binding.BypassProxyOnLocal = false;
binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
binding.MessageEncoding = WSMessageEncoding.Text;
binding.TextEncoding = Encoding.UTF8;
binding.TransferMode = TransferMode.Buffered;
binding.UseDefaultWebProxy = true;
binding.MaxReceivedMessageSize = 5242880;
return new EServiceAPI.EServiceClient(binding, new EndpointAddress(url));
}
If it works you can modify the settings above to suit your needs better.

I think this has to do with the <endpoint address="http://Domane.dk/EService.svc" i believe it should be a relative path when using on a server.
Like:
<endpoint address="./EService.svc"

Related

WCF Named Pipe in Windows Service using App.Config

I am frustrated. Okay, here is the error.
There was no endpoint listening at net.pipe://localhost/MyIpcAppToService that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
I finally got the App.Config file working, at least no complaints.
Current App.Config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup>
<system.serviceModel>
<services>
<service behaviorConfiguration="MyServiceBehavior" name="MyService.Communication.IpcAppToService">
<endpoint address="net.pipe://localhost/MyIpcAppToService" binding="wsDualHttpBinding" bindingConfiguration="MyAppToServiceEndpointBinding" contract="MyIpc.IIpcAppToService"/>
<endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/MyService/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add scheme="http" binding="wsHttpBinding" bindingConfiguration="MyAppToServiceEndpointBinding" />
</protocolMapping>
<bindings>
<wsDualHttpBinding>
<!-- https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/wshttpbinding -->
<binding name="MyAppToServiceEndpointBinding"
transactionFlow="true"
sendTimeout="00:01:00"
maxReceivedMessageSize="2147483647"
messageEncoding="Mtom">
</binding>
</wsDualHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
<baseAddressPrefixFilters>
<add prefix="http://localhost:8733"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
</system.serviceModel>
<appSettings>
<add key="countoffiles" value="7"/>
<add key="logfilelocation" value="abc.txt"/>
</appSettings>
</configuration>
I used to have:
<endpoint address="http://localhost:8733/MyIpcAppToService" ...
and in the Windows Service OnStart() event:
(this following code is now commented out, as of this question post, as the App.config file is supposed to start the named.pipe.)
public Boolean CreatePipeServer()
{
string eventText = $"My Service: CommAppToService::CreatePipeServer(IPC App to Service){Environment.NewLine}";
try
{
if (null != this.ServiceParent.HostIpcAppToService)
this.ServiceParent.HostIpcAppToService = null;
string pipeBaseAddress = #"net.pipe://localhost/MyIpcAppToService";
this.ServiceParent.HostIpcAppToService = new ServiceHost(typeof(IpcAppToService), new Uri(pipeBaseAddress));
NetNamedPipeBinding pipeBinding = new NetNamedPipeBinding()
{
//ReceiveTimeout = new TimeSpan(0, 0, 0, 0, Constants.My_TimeoutMsSendReceive),
//SendTimeout = new TimeSpan(0, 0, 0, 0, Constants.My_TimeoutMsSendReceive),
};
this.ServiceParent.HostIpcAppToService.AddServiceEndpoint(typeof(IIpcAppToService), pipeBinding, "MyIpcAppToService");
this.ServiceParent.HostIpcAppToService.UnknownMessageReceived += HostIpcAppServer_UnknownMessageReceived;
this.ServiceParent.HostIpcAppToService.Faulted += HostIpcAppServer_Faulted;
this.ServiceParent.HostIpcAppToService.Closing += HostIpcAppServer_Closing;
this.ServiceParent.HostIpcAppToService.Closed += HostIpcAppServer_Closed;
this.IpcAppToService = new IpcAppToService();
this.IpcAppToService.ApplyDispatchBehavior(this.ServiceParent.HostIpcAppToService);
this.IpcAppToService.Validate(this.ServiceParent.HostIpcAppToService);
this.ServiceParent.HostIpcAppToService.Open();
return true;
}
I read that the service will AUTOMATICALLY start services placed in the App.Config file, really the MyExeName.exe.config file. I kept looking at the code and saw that it was nearly identical, so I replaced the http:// with net.pipe://.
Sadly, old code, new code, in between code, all nothing. I keep receiving the same error.
I use the following to connect to the service from my desktop application.
public static Boolean ConnectToService()
{
try
{
var callback = new IpcCallbackAppToService();
var context = new InstanceContext(callback);
var pipeFactory = new DuplexChannelFactory<IIpcAppToService>(context, new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/MyIpcAppToService"));
Program.HostIpcAppToService = pipeFactory.CreateChannel();
Program.HostIpcAppToService.Connect();
CommAppToService.IsPipeAppToService = true;
return true;
}
catch (Exception ex)
{
// Log the exception.
Errors.LogException(ex);
}
return false;
}
For whatever it is worth, here is:
Interface
[ServiceContract(SessionMode = SessionMode.Allowed, CallbackContract = typeof(IIpcCallbackAppToService))]
public interface IIpcAppToService
{
[OperationContract(IsOneWay = false)]
[FaultContractAttribute(typeof(IpcAppToServiceFault))]
UInt16 GetServiceId();
...
}
Service:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class IpcAppToService : IIpcAppToService, IErrorHandler
{
public static IIpcCallbackAppToService Callback { get; set; } = null;
public void OpenCallback()
{
IpcAppToService.Callback = OperationContext.Current.GetCallbackChannel<IIpcCallbackAppToService>();
}
public void CloseCallback()
{
IpcAppToService.Callback = null;
}
public void SendMessage(string message)
{
//MessageBox.Show(message);
}
public UInt16 GetServiceId()
{
return Constants.My_Id_AppToService;
}
...
}
Inner Exception from my desktop WinForms Application
(Note, there were no further inner exceptions than this one.):
"The pipe endpoint 'net.pipe://localhost/MyIpcAppToService' could not be found on your local machine."
Why do I keep seeing this error?
UPDATE AFTER 1ST ANSWER
The direction that I would like to take is opposite of the answer, yet the same, namely that the service starts with the App.config and the client uses C# code.
Sadly, I still get the same error.
Revised Server Side App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup>
<system.serviceModel>
<services>
<service behaviorConfiguration="BehaviorMyService" name="MyService.Communication.IpcAppToService">
<endpoint address="net.pipe://localhost/MyIpcAppToService"
binding="netNamedPipeBinding"
bindingConfiguration="EndpointBindingMyAppToService"
contract="MyIpc.IIpcAppToService"
/>
<endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/MyService/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="BehaviorMyService">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true"
httpsGetEnabled="true"
/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netNamedPipeBinding>
<!-- https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/wshttpbinding -->
<binding name="EndpointBindingMyAppToService"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00"
sendTimeout="00:01:00"
transactionFlow="false"
transferMode="Buffered"
transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288"
maxBufferSize="65536"
maxConnections="10"
maxReceivedMessageSize="2147483647"
>
<security mode="None">
<transport protectionLevel="None" />
</security>
</binding>
</netNamedPipeBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
<baseAddressPrefixFilters>
<add prefix="http://localhost:8733"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
</system.serviceModel>
<appSettings>
<add key="countoffiles" value="7"/>
<add key="logfilelocation" value="abc.txt"/>
</appSettings>
</configuration>
Revised Client Side C# Code:
var callback = new IpcCallbackAppToService();
InstanceContext context = new InstanceContext(callback);
NetNamedPipeBinding binding = new NetNamedPipeBinding();
binding.Security.Mode = NetNamedPipeSecurityMode.None;
EndpointAddress endpointAddress = new EndpointAddress("net.pipe://localhost/MyIpcAppToService");
var pipeFactory = new DuplexChannelFactory<IIpcAppToService>(context, binding, endpointAddress);
Program.HostIpcAppToService = pipeFactory.CreateChannel();
Program.HostIpcAppToService.Connect();
CommAppToService.IsPipeAppToService = true;
The service throws no exceptions that I can detect, as the EventViewer is clean, just the OnStart() successfully completed message. I know that the system processes the App.config file, as previously when I had errors, the Windows Event Viewer would keep complaining, but not anymore.
Here were some of the Microsoft docs that I used:
netNamedPipeBinding
netNamedPipeBinding2
I did try IO Ninja, but specifying \\.\pipe\MyIpcToService for File Stream, Pipe Listener, and Pipe Monitor, but nothing shows there, even when I try to connect using my WinForms desktop application, which then throws the no pipe listener found exception.
What can be the problem?
<endpoint address="net.pipe://localhost/MyIpcAppToService" binding="wsDualHttpBinding" bindingConfiguration="MyAppToServiceEndpointBinding" contract="MyIpc.IIpcAppToService"/>
Make sure that the service address is in the same form (transport protocol) as the binding type.
TCP(net.tcp://localhost:8000/myservice) NetTcpBinding
IPC(net.pipe://localhost/mypipe) NetNamedPipeBinding
Http/Https(http://localhost:8000/myservice)
Wshttpbinding,Wsdualhttpbinding,basichttpbinding
WebSocket(ws://localhost:3434) Nethttpbinding
MSMQ(net.msmq://localhost/private/myservice) NetMsmqBinding
we are supposed to use NetnamedPipeBinding for the service address. Please refer to my example.
Updated
I have a wcf service using NetNamedPipeBinding hosted in IIS, wish it is useful to you.
Server(wcf service application)
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
}
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
Web.config(Server side)
<system.serviceModel>
<services>
<service behaviorConfiguration="BehaviorMyService" name="WcfService1.Service1">
<endpoint address="MyIpcAppToService"
binding="netNamedPipeBinding"
bindingConfiguration="EndpointBindingMyAppToService"
contract="WcfService1.IService1"
/>
<endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="BehaviorMyService">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netNamedPipeBinding>
<binding name="EndpointBindingMyAppToService"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00"
sendTimeout="00:01:00"
transactionFlow="false"
transferMode="Buffered"
transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288"
maxConnections="10"
maxReceivedMessageSize="2147483647"
>
<security mode="None">
<transport protectionLevel="None" />
</security>
</binding>
</netNamedPipeBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
</serviceHostingEnvironment>
</system.serviceModel>
Enable WCF new feature.
IIS site(enable net.pipe)
Client(console application)
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
var result = client.GetData(34);
Console.WriteLine(result);
Client app.config(auto-generated)
I use the http address(service metadata GET address http://localhost:8733/Service1.svc?wsdl) to generated the configuration.
<system.serviceModel>
<bindings>
<netNamedPipeBinding>
<binding name="NetNamedPipeBinding_IService1">
<security mode="None" />
</binding>
</netNamedPipeBinding>
</bindings>
<client>
<endpoint address="net.pipe://mynetpipe/Service1.svc/MyIpcAppToService"
binding="netNamedPipeBinding" bindingConfiguration="NetNamedPipeBinding_IService1"
contract="ServiceReference1.IService1" name="NetNamedPipeBinding_IService1" />
</client>
</system.serviceModel>
Feel free to let me know if there is anything I can help with.

Pass Windows credentials to remote https WCF service

I need some help, I'm trying to pass windows credentials to a WCF service. In the IIS only Windows authentication is enabled for those service and runs over https.
The server side config is:
<system.serviceModel>
<protocolMapping>
<add scheme="https" binding="basicHttpBinding" bindingConfiguration="httpsBinding"/>
</protocolMapping>
<bindings>
<basicHttpBinding>
<binding name="httpsBinding">
<security mode="Transport">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
and in the client side:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMyService" maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://myserver.net:4343/MyService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyService"
contract="MyServiceReference.IMyService" name="BasicHttpBinding_IMyService" />
</client>
I'm trying to consume the service on this way:
Client = new MyServiceClient();
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
binding.MaxReceivedMessageSize = int.MaxValue;
binding.MaxBufferPoolSize = long.MaxValue;
binding.MaxBufferSize = int.MaxValue;
EndpointAddress ep = new EndpointAddress("https://myserver.net:4343/MyService.svc");
Client = new COMINTSServiceClient(binding, ep);
Client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Identification;
Client.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
Client.Open();
Array[] obj = Client.RandomMethod();
This code doesn't work for me:
Client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Identification;
Client.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
In the service when ask for the user who is calling to the service using ServiceSecurityContext.Current.WindowsIdentity.Name allways get: ISS APPPOOL\ASP.NET v4.0 instead of the domain\user who is calling
The only way to make it work is write the username and password instead DefaultNetworkCredentials.
Client.ClientCredentials.Windows.ClientCredential.UserName = "DOMAIN\\user";
Client.ClientCredentials.Windows.ClientCredential.Password = "passw";
But I don't want a user/passw hardcoded.
Any help please?
Try:
Client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
Keep the assignment from CredentialCache.
I faced with similar issue - "ServiceSecurityContext.Current.WindowsIdentity.Name" on the server side returned wrong username, not Current Windows User on the client side. Turns out "Client.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials" may get credentials from Windows Credential Manager:
I failed to find a solution to instruct WCF to avoid grabbing credentials from that storage. The workaround was to check if some credentials are stored for that IP address and remove them. I used "https://www.nuget.org/packages/CredentialManagement" for checking and removing. Here is the code:
var creds = new Credential();
creds.Type = CredentialType.DomainPassword;
creds.Target = address.Uri.Host;//address is WCF EndpointAddress
if (creds.Load() && creds.Username != System.Security.Principal.WindowsIdentity.GetCurrent().Name)
{
creds.Delete();
}

Converting a WCF config file into code

I am currently using an auto-generated proxy for a Web Service. It's going to be part of a library and I can't use the *.config file. In the past I've just converted the .config code to C# code, but in this case the .config file is a bit more complex than what I've used in the past and I'm struggling to find enough samples to get this converted.
<system.serviceModel>
<extensions>
<bindingElementExtensions>
<add name="CustomMessageEncoder" type="SampleAPI.CustomMessageEncoderBindingElementExtensionElement, SampleAPI" />
</bindingElementExtensions>
</extensions>
<bindings>
<customBinding>
<binding name="DeviceInfoServiceBinding">
<CustomMessageEncoder></CustomMessageEncoder>
<security authenticationMode="CertificateOverTransport"
allowSerializedSigningTokenOnReply="true"
enableUnsecuredResponse="true"
messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" >
</security>
<httpsTransport maxReceivedMessageSize="2000000"></httpsTransport>
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="https://ws.sample.com/DeviceQuery/v1"
binding="customBinding"
bindingConfiguration="DeviceInfoServiceBinding"
contract="TestWS.DeviceInfoServiceType"
behaviorConfiguration="CertBehavior"
name="DeviceInfoServiceType">
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="CertBehavior">
<clientCredentials>
<clientCertificate storeLocation="CurrentUser"
storeName="My"
findValue="Sample"
x509FindType="FindByIssuerName" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
Any help with converting the above is appreciated.
I ended up looking at one of my other projects and just pulled over the things I knew how to do. I was able to get this working, although I couldn't quite figure out how to configure one of the properties (AllowSerializedSigningTokenOnReply). However, it still seemed to work OK.
Here's what I did, hopefully this will save someone the headache of figuring this out:
var binding = new CustomBinding();
binding.Elements.Add(new CustomMessageEncoderBindingElement());
var sec = SecurityBindingElement.CreateCertificateOverTransportBindingElement();
// AllowSerializedSigningTokenOnReply = true
sec.EnableUnsecuredResponse = true;
sec.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;
binding.Elements.Add(sec);
binding.Elements.Add(new HttpsTransportBindingElement() { MaxReceivedMessageSize = 2000000 });
var endpoint = new EndpointAddress("https://ws.sample.com/DeviceQuery/v1");
var client = new TestWS.DeviceInfoServiceTypeClient(binding, endpoint);
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser,
StoreName.My,
X509FindType.FindByIssuerName,
"Sample");

WCF client in a universal app

Is it possible to call a WCF service from a universal application?
I added a service reference and the proxy was generated just fine.
But when creating a NetTcpBinding programmatically and passing that to the proxy's constructor the service model throws the exception PlatformNotSupported.
Both running the app in the simulator and on the local machine generates the same exception.
An exception of type 'System.PlatformNotSupportedException' occurred
in System.Private.ServiceModel.dll but was not handled in user code
"this operation is not supported"
EndpointAddress address = new EndpointAddress("net.tcp://test:9000/ServicesHost/PublishService");
NetTcpBinding binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.None;
PublishingService.PublishClient proxy = new PublishingService.PublishClient(binding, address);
Does anybody have an example of a working WCF client in a UAP?
EDIT
It has something to do with the service being a duplex service!
The original contract:
[ServiceContract(CallbackContract = typeof(IPublishCallback))]
public interface IPublish { }
After removing the CallbackContract attribute the UAP client can create a connection, so basic WCF works.
So I guess it's better to rephrase the question.
Is it possible to create a duplex WCF client in a universal application?
edit servicemodel for the host
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="netTcpPublishService" openTimeout="00:00:10" receiveTimeout="infinite">
<reliableSession inactivityTimeout="24.20:31:23.6470000" enabled="true" />
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehaviour">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="serviceBehaviour" name="PublishService.Publish">
<endpoint binding="mexHttpBinding" name="mexPublishService"
contract="IMetadataExchange" />
<endpoint address="PublishService" binding="netTcpBinding" bindingConfiguration="netTcpPublishService"
name="netTcpPublishService" contract="PublishService.IPublish" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8004/ServicesHost/PublishService" />
<add baseAddress="net.tcp://localhost:9004/ServicesHost/PublishService" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
Yes, it is possible. This is how i connect in a sample app i did a while ago:
using Tradeng.Srvc.Client.WinAppSimple.SrvcRefTradeng;
private InstanceContext instanceContext;
private TradengSrvcClientBase serviceProxy;
instanceContext = new InstanceContext(this);
serviceProxy = new TradengSrvcClientBase(instanceContext);
bool result = await serviceProxy.ConnectAsync();
if (result)
{
// connected...
}
I used the binding from the config file that is generated when you add a reference to your service.
This is what the app looks like. Cutting edge stuff.... :O)
https://www.youtube.com/watch?v=YSg6hZn1DpE
The service itself is running as a WebRole on Azure, by the way.

The remote server returned an unexpected response: (400) Bad Request while streaming

I have problem with streaming. When I send small file like 1kb txt everything is ok, but when I send larger file like 100 kb jpg or 2gb psd I get:
The remote server returned an unexpected response: (400) Bad Request.
I'm using windows 7, VS 2010 and .net 3.5 and WCF Service library
I lost all my weekend on this and I still see this error :/ Please help me
Client:
var client = new WpfApplication1.ServiceReference1.Service1Client("WSHttpBinding_IService1");
client.GetString("test");
string filename = #"d:\test.jpg";
FileStream fs = new FileStream(filename, FileMode.Open);
try
{
client.ProcessStreamFromClient(fs);
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="StreamedHttp" closeTimeout="10:01:00" openTimeout="10:01:00"
receiveTimeout="10:10:00" sendTimeout="10:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536000" maxBufferPoolSize="524288000" maxReceivedMessageSize="65536000"
messageEncoding="Text" textEncoding="utf-8" transferMode="Streamed"
useDefaultWebProxy="true">
<readerQuotas maxDepth="0" maxStringContentLength="0" maxArrayLength="0"
maxBytesPerRead="0" maxNameTableCharCount="0" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary2/Service1/"
binding="basicHttpBinding" bindingConfiguration="StreamedHttp"
contract="ServiceReference1.IService1" name="WSHttpBinding_IService1" />
</client>
</system.serviceModel>
</configuration>
And Wcf ServiceLibrary:
public void ProcessStreamFromClient(Stream str)
{
//error occuring even this method is empty
using (var outStream = new FileStream(#"e:\test.jpg", FileMode.Create))
{
var buffer = new byte[4096];
int count;
while ((count = str.Read(buffer, 0, buffer.Length)) > 0)
{
outStream.Write(buffer, 0, count);
}
}
}
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="Binding1"
hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536000"
transferMode="Streamed"
bypassProxyOnLocal="false"
closeTimeout="10:01:00"
openTimeout="10:01:00" receiveTimeout="10:10:00" sendTimeout="10:01:00"
maxBufferPoolSize="524288000" maxReceivedMessageSize="65536000" messageEncoding="Text"
textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<client />
<services>
<service name="WcfServiceLibrary2.Service1">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary2/Service1/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary2.IService1">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Try setting:
<serviceDebug includeExceptionDetailInFaults="true" />
It will not solve the problem, but you may get an error message stating what the problem is.

Categories

Resources