I am using custom binding in the sevrice side in C#. I want binary Encoding in HTTP.
<bindings>
<customBinding>
<binding name="myOwnBinding">
<binaryMessageEncoding></binaryMessageEncoding>
<httpTransport/>
</binding>
</customBinding>
</bindings>
<extensions>
<bindingExtensions>
<add name="myOwnBinding" type="CustomBinding.UserBinding,CustomBinding"/>
</bindingExtensions>
</extensions>
<service name="CustomBinding.Service1" behaviorConfiguration="CustomBinding.Service1Behavior">
This service is not going to expose the metadata.So,i will not be able to create a service Reference in client to consume the servvice.
Now,I want to know how to use this binding in the client channel factory to consume this service.Below is my client side code.
EndpointAddress address = new EndpointAddress("http://localhost:2418/Service1.svc");
ChannelFactory<IService1> c = new ChannelFactory<IService1>(Binding, address);
IService1 reqChannel = c.CreateChannel();
String str = reqChannel.GetData(1);
How to manually fill the binding object that the Channel factory is expecting when service is developed with custom binding.?
Thanks
Arun
I have sorted it out when i used the app.config to load the custom binding object.
System.ServiceModel.Channels.CustomBinding cus = new System.ServiceModel.Channels.CustomBinding("CustomBinding_IService1");
EndpointAddress address = new EndpointAddress("http://localhost:2418/Service1.svc");
ChannelFactory<IService1> c = new ChannelFactory<IService1>(cus);
IService1 serviceInstance = c.CreateChannel(address);
String str = serviceInstance.GetData(1);
Thanks
Related
I am working on a project that uses WCF service. I have built the service, configured the web.config file, deployed it on a IIS 7 server. The service is accesed through HTTPS (on my dev machine, i have self-created the certificate).
Everything is fine when a create the ServiceReference in Visual Studio 2010, it creates the client and it works fine.
What i need is to create a client programatically (need a little flexibility), so when i try to connect "manually", it gives me a error like this:
The provided URI scheme 'https' is invalid; expected 'http'.
Parameter name: via
The code for web.config is: (i hope there is nothing wrong in it)
<system.serviceModel>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="WcfService1.Service1Behavior">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="TransportSecurity" contract="WcfService1.IService1" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfService1.Service1Behavior">
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="TransportSecurity">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
The procedure i wrote to access the WCF service is:
void proc()
{
string ADRESASSL = "https://localhost/ServiciuSSLwsBind/Service1.svc";
WSHttpBinding bind= new WSHttpBinding();
EndpointAddress ea = new EndpointAddress(ADRESASSL);
var myChannelFactory = new ChannelFactory<IService1>(bind, ea);
IService1 client = null;
try
{
client = myChannelFactory.CreateChannel();
client.RunMethod1();
client.Close();
//((ICommunicationObject)client).Close();
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
if (client != null)
client.Close();
}
}
The code for IService1
[ServiceContract]
public interface IService1 : IClientChannel
{
[OperationContract]
int RunMethod1();
//....................................
}
It seems i am doing something wrong here, the procedure raises the Exception i mentioned. Something more i must do to work, but i didn't figured it out.
Thanks in advance for any advice you can give me.
I haven't tested this, but I believe you need to set the security mode for the binding before you create the factory. The default mode for security for WSHttpBinding is SecurityMode.Message, and you want SecurityMode.Transport.
You can resolve this one of three ways, as follows.
First, you can use the overloaded version of the WSHttpBinding constructor to specify the security mode, like this:
WSHttpBinding bind= new WSHttpBinding(SecurityMode.Transport);
bind.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
Secondly, you can use the parameterless constructor and specify the security mode (and the client credential type) like this:
WSHttpBinding bind= new WSHttpBinding();
bind.Security.Mode = SecurityMode.Transport;
bind.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
Third, you can place a binding configuration section in the client config and reference that section in the constructor, like this:
WSHttpBinding bind = new WSHttpBinding("TransportSecurity");
The third example assumes a wsHttpBinding section with the name "TransportSecurity" in the client config file.
For more information, check these MSDN articles:
How to: Set the Security Mode
WSHttpBinding Constructor
Well, solved the problem with the self created certificate.
I have changed the endpoint adress for both the programatically connection and the service reference in Viosual Studio 2010.
string ADRESASSL = "https://localhost/ServiciuSSLwsBind/Service1.svc";
now is
string ADRESASSL = "https://eu-pc/ServiciuSSLwsBind/Service1.svc";
I have changed the adress from localhost to the name of pc "eu-pc". It has to do with the domain the certificate was issued.
Using localhost or 127.0.0.1 worked only for one method or the other.
Hope this will help other guys who might run into this.
One of my WCF Services has an operation contract taking a large sized file as a parameter. So, when the client tries to send this over, I got an exception and when I looked at the server trace this is what I saw:
MESSAGE: The maximum message size quota for incoming messages (65536)
has been exceeded. To increase the quota, use the
MaxReceivedMessageSize property on the appropriate binding element.
I was using the default simplified configuration for my WCF services, so added a new service definition as follows:
<system.serviceModel>
<services>
<service name="MyNamespace.MyService">
<endpoint address="MyService.svc"
binding="basicHttpBinding" bindingConfiguration="basicHttp"
contract="MyNamespace.IMyService" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="basicHttp" allowCookies="true"
maxReceivedMessageSize="10485760"
maxBufferSize="10485760"
maxBufferPoolSize="10485760">
<readerQuotas maxDepth="32"
maxArrayLength="10485760"
maxStringContentLength="10485760"/>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
...
</behaviors>
<protocolMapping>
...
</protocolMapping>
The way I consume my services is, I have a function returning a channel in my helper class, and I use that channel to call the operations:
public static T CreateChannel<T>() where T : IBaseService
{
System.ServiceModel.BasicHttpBinding binding= new System.ServiceModel.BasicHttpBinding();
binding.TransferMode = TransferMode.Streamed;
binding.Security = new BasicHttpSecurity() { Mode = BasicHttpSecurityMode.None };
binding.MaxReceivedMessageSize = 10485760;
binding.MaxBufferSize = 10485760;
System.ServiceModel.ChannelFactory<T> cf2 = new ChannelFactory<T>(binding,
new System.ServiceModel.EndpointAddress(MyEndpointAddress)); //I checked this part, the address is correct.
T Channel= cf2.CreateChannel();
return Channel;
}
and then,
var businessObject = WcfHelper.CreateChannel<IMyService>();
var operationResult = await businessObject.MyOperationAsync(...);
Even though, my other services are running correctly, the one I defined in the configuration explicitly returns an exception of "There was no endpoint listening..." I am developing on VS2012, using IISExpress. What may be the problem, any suggestions?
I think there is a mismatch for transfert mode. In client-side, you are are using streamed transfert whereas in server-side it is not in the config. In addition, you have specified 10MB, which is not so high.
Please visit this for more info on streaming.
Edit :
If you are hosting under IIS, please also check (default is 4Mb) :
<system.web>
<httpRuntime maxRequestLength="4096 " />
</system.web>
I have a WCF SOAP service that uses basic access authentication. SSL is not being used - I understand the security issues here.
Using the WCFTestClient application I have verified the service works by temporarily hard coding into the service a user name and password to use when the Authorization header is not present.
I am now trying to write a test application that passes the credentials via the Authorization header. I've added a service reference to my service in my test app but the Authorization header is not present in the http request. The generated MyServiceClient class uses System.ServiceModel.ClientBase
In my test app I am setting the credentials as follows
MyServiceClient client = new MyServiceClient("BasicHttpBinding_MyService");
client.ClientCredentials.UserName.UserName = "WebServiceUsername";
client.ClientCredentials.UserName.Password = "WebServicepassword";
I have also tried as follows
MyServiceClient client = new MyServiceClient();
ClientCredentials loginCredentials = new ClientCredentials();
loginCredentials.UserName.UserName = "WebServiceUsername";
loginCredentials.UserName.Password = "WebServicepassword";
client.Endpoint.Behaviors.Remove(client.Endpoint.Behaviors.Find<ClientCredentials>());
client.Endpoint.Behaviors.Add(loginCredentials);
The service web.config is as follows
<services>
<service name="MyService" behaviorConfiguration="MyBehavior" >
<endpoint contract="MyService" binding="basicHttpBinding" />
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
</service>
</services>
The test app.config is as follows
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_MyService">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:55314/MyService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_MyService"
contract="MyService" name="BasicHttpBinding_MyService" />
</client>
</system.serviceModel>
</configuration>
Any thoughts on what I am missing?
This is a good starting point, move your binding and endpoint info from config file to your class:
protected BasicHttpBinding binding = new BasicHttpBinding()
{
Name = "Name your binding here",
CloseTimeout = new TimeSpan(0, 1, 0),
OpenTimeout = new TimeSpan(0, 1, 0),
ReceiveTimeout = new TimeSpan(0, 10, 0),
SendTimeout = new TimeSpan(0, 1, 0),
AllowCookies = false,
BypassProxyOnLocal = false,
HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,
MaxBufferSize = 65536,
MaxBufferPoolSize = 524288,
MaxReceivedMessageSize = 65536,
MessageEncoding = WSMessageEncoding.Text,
TransferMode = TransferMode.Buffered,
UseDefaultWebProxy = true,
Security = new BasicHttpSecurity()
{
Mode = BasicHttpSecurityMode.Transport,
Message = new BasicHttpMessageSecurity() { AlgorithmSuite = SecurityAlgorithmSuite.Default, ClientCredentialType = BasicHttpMessageCredentialType.UserName},
Transport = new HttpTransportSecurity() { ClientCredentialType = HttpClientCredentialType.Digest }
},
};
protected EndpointAddress endPoint = new EndpointAddress("http://localhost:55314/MyService.svc");
and then
MyServiceClient client = new MyServiceClient(binding, endpont);
Try this, and tweak the binding into your needs, especially "Security".
BasicHttpBinding doesn't seem to have a Security Property in WP8, I am very frustrated with trying to access a sharepoint list under WP8. Xamarin IOS/Android it is no problem.
We're developing a Silverlight Client onto a server-based API exposed via WCF.
I'm trying to move my WCF client code (which works fine) from a configuration-based model to a programmatic model. This will enable me to have a single "root" URL which I can apply at start-up and not require installations to have to maintain humongous configuration files.
I'm stuggling converting my configurations to Silverlight-capable code, though.
Where I have the configuration below for one of my services:
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomBinding_ISilverlightHelper">
<binaryMessageEncoding />
<httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647">
<extendedProtectionPolicy policyEnforcement="Never" />
</httpTransport>
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://localhost:50072/API/WCF/Silverlight/SilverlightHelper.svc"
binding="customBinding" bindingConfiguration="CustomBinding_ISilverlightHelper"
contract="API.WCF.Silverlight.ISilverlightHelper" name="CustomBinding_ISilverlightHelper" />
</client>
</system.serviceModel>
</configuration>
I can't figure out how to create the equivelant client-config code. At the moment I have:
CustomBinding customBinding = new CustomBinding();
// I see I need to do something with customBinding but the properties don't seem
// logical
// I have used BasicHttpBinding, but it just returns with "Not Found" (the service does resolve to a valid URL)
BasicHttpBinding basicHttpBinding = new BasicHttpBinding() { MaxBufferSize = int.MaxValue, MaxReceivedMessageSize = int.MaxValue };
EndpointAddress endpointAddress = new EndpointAddress("http://localhost:50072/API/WCF/Silverlight/SilverlightHelper.svc");
ISilverlightHelper silverlightHelper= new ChannelFactory<ISilverlightHelper>(basicHttpBinding, endpointAddress).CreateChannel();
AsyncCallback asyncCallback = delegate(IAsyncResult result)
{
ISilverlightHelper asyncSilverlightHelper = (ISilverlightHelper)result.AsyncState;
string[] files=asyncSilverlightHelper.EndGetPlugInXapNames(result).ToArray();
};
silverlightHelper.BeginGetPlugInXapNames(asyncCallback, silverlightHelper);
Any clues would be appreciated. I've spent all morning Googling/Binging/Overflowing but haven't come across this scenario. Or I might be just so far wrong ...
Sorted it.
I created the BinaryMessageEncodingBindingElement and HttpTransportBindingElements, added them to the CustomBinding and it all works.
Here's my annotated code:
// create the binding elements
BinaryMessageEncodingBindingElement binaryMessageEncoding = new BinaryMessageEncodingBindingElement();
HttpTransportBindingElement httpTransport = new HttpTransportBindingElement() { MaxBufferSize = int.MaxValue, MaxReceivedMessageSize = int.MaxValue };
// add the binding elements into a Custom Binding
CustomBinding customBinding = new CustomBinding(binaryMessageEncoding,httpTransport);
// create the Endpoint URL (I'll use a configured URL later - all web services will then move as one)
EndpointAddress endpointAddress = new EndpointAddress("http://localhost:50072/API/WCF/Silverlight/SilverlightHelper.svc");
// create an interface for the WCF service
ISilverlightHelper silverlightHelper= new ChannelFactory<ISilverlightHelper>(customBinding, endpointAddress).CreateChannel();
// set-up the asynchronous callback
AsyncCallback asyncCallback = delegate(IAsyncResult result)
{
ISilverlightHelper asyncSilverlightHelper = (ISilverlightHelper)result.AsyncState;
string[] files=asyncSilverlightHelper.EndGetPlugInXapNames(result).ToArray();
};
// execute the call
silverlightHelper.BeginGetPlugInXapNames(asyncCallback, silverlightHelper);
How do I increase the default timeout to larger than 1 minute on a WCF service?
Are you referring to the server side or the client side?
For a client, you would want to adjust the sendTimeout attribute of a binding element. For a service, you would want to adjust the receiveTimeout attribute of a binding elemnent.
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="longTimeoutBinding"
receiveTimeout="00:10:00" sendTimeout="00:10:00">
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="longTimeoutService"
behaviorConfiguration="longTimeoutBehavior">
<endpoint address="net.tcp://localhost/longtimeout/"
binding="netTcpBinding" bindingConfiguration="longTimeoutBinding" />
</service>
....
Of course, you have to map your desired endpoint to that particular binding.
Under the Tools menu in Visual Studio 2008 (or 2005 if you have the right WCF stuff installed) there is an options called 'WCF Service Configuration Editor'.
From there you can change the binding options for both the client and the services, one of these options will be for time-outs.
You can choose two ways:
1) By code in the client
public static void Main()
{
Uri baseAddress = new Uri("http://localhost/MyServer/MyService");
try
{
ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService));
WSHttpBinding binding = new WSHttpBinding();
binding.OpenTimeout = new TimeSpan(0, 10, 0);
binding.CloseTimeout = new TimeSpan(0, 10, 0);
binding.SendTimeout = new TimeSpan(0, 10, 0);
binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
serviceHost.AddServiceEndpoint("ICalculator", binding, baseAddress);
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
}
catch (CommunicationException ex)
{
// Handle exception ...
}
}
2)By WebConfig in a web server
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding openTimeout="00:10:00"
closeTimeout="00:10:00"
sendTimeout="00:10:00"
receiveTimeout="00:10:00">
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
For more detail view the official documentations
Configuring Timeout Values on a Binding
Class WSHttpBinding
Different timeouts mean different things. When you're working on the client.. you're probably looking mostly at the SendTimeout - check this reference - wonderful and relevant explanation:
http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/84551e45-19a2-4d0d-bcc0-516a4041943d/
It says:
Brief summary of binding timeout knobs...
Client side:
SendTimeout is used to initialize the OperationTimeout, which governs the whole interaction for sending a message (including receiving a reply message in a request-reply case). This timeout also applies when sending reply messages from a CallbackContract method.
OpenTimeout and CloseTimeout are used when opening and closing channels (when no explicit timeout value is passed).
ReceiveTimeout is not used.
Server side:
Send, Open, and Close Timeout same as on client (for Callbacks).
ReceiveTimeout is used by ServiceFramework layer to initialize the session-idle timeout.
In addition to the binding timeouts (which are in Timespans), You may also need this as well. This is in seconds.
<system.web>
<httpRuntime executionTimeout="600"/><!-- = 10 minutes -->