I'm working on implementing some code in C# using a web service, but my only reference is a Java code they used to load test.
Java gets the object calling by calling this
lotService=(LotService) ic.lookup("mes-webservices/lotService/remote");
where IC is an InitialContext object.
I need to do this same call on C# but I have no idea how. Is there a simple way just like this java method to do it in C#?
You can do similar thing in C# by adding service reference to web service. I assume your webservice and consuming client are both in .NET.
Psuedo code would be
LocationWebService objService = new LocationWebService(); // this is proxy class of web service created when you add web reference
string result = objService.GetLocationName(4); //call web method
Below are the steps:
Add service refrence in your project
Create ServiceClient instance
By using above created instance call methods it is exposing
That is it.
First right-click your project and select "Add Service Reference."
Once you have it you need to create the service client object. Whatever you named your service reference above you'll have a new type available in your project (named, I think, the service reference name appended with "Client" on the end. Example: if the service is FooService, you'll have a client type called FooServiceClient available.)
To instantiate, you need a binding. You can create it programmatically:
var binding = new BasicHttpBinding()
{
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,
TextEncoding = Encoding.UTF8,
TransferMode = TransferMode.Buffered,
UseDefaultWebProxy = true
};
binding.ReaderQuotas.MaxDepth = 32;
binding.ReaderQuotas.MaxStringContentLength = 8192;
if (isHttps)
binding.Security = new BasicHttpSecurity() { Mode = BasicHttpSecurityMode.Transport };
Then you need an endpoint. Create like so:
var endpoint = new EndpointAddress(serviceUri);
Then just instantiate the service client:
var serviceClient = new FooServiceClient(binding, endpoint);
You can call your service methods from the service client instance.
Related
My system is composed of a bunch of WCF services that can be used by various clients.
The first thing I do is to run the services in interactive mode (I have a console popping and letting me know the service is started).
I can then run a given client that excercises any of my WCF services. When instantiated the client create a channel and associated timeouts in the following way:
var ctx = new InstanceContext(TestCallbackProxy.Instance);
string baseAddress = Constants.ServiceBaseAddress;
var binding = new NetNamedPipeBinding();
binding.MaxConnections = 10;
binding.OpenTimeout = System.TimeSpan.FromMinutes(1);
binding.CloseTimeout = System.TimeSpan.FromMinutes(1);
binding.ReceiveTimeout = System.TimeSpan.FromMinutes(5);
binding.SendTimeout = System.TimeSpan.FromMinutes(5);
var channelFactory = new DuplexChannelFactory<ITestService>(ctx, binding, new EndpointAddress(baseAddress + serviceName));
// Create channel to a specified endpoint
_channel = channelFactory.CreateChannel() as ITestService;
Now, the service eventually times out when left unused for a while, which from my understanding is expected. ie. The channel will simply vanish/be discarded by the system if unused - Something to do with reusablility and optimisation I believe.
However, when trying to prove this theory and reducing all the timeouts, I cannot get the service to break. ie. Should the service not timeout/break when trying to use it when left alone for more than 30sec? Used timeouts are:
binding.OpenTimeout = System.TimeSpan.FromMinutes(0.5);
binding.CloseTimeout = System.TimeSpan.FromMinutes(0.5);
binding.ReceiveTimeout = System.TimeSpan.FromMinutes(0.5);
binding.SendTimeout = System.TimeSpan.FromMinutes(0.5);
I think the reason is that you should be setting your timeouts on the service side, where you are setting up your hosts and defining endpoints, not on the client side. Here is an example:
var binding = new NetNamedPipeBinding();
binding.MaxConnections = 10;
binding.OpenTimeout = TimeSpan.FromMinutes(0.5);
binding.CloseTimeout = TimeSpan.FromMinutes(0.5);
binding.ReceiveTimeout = TimeSpan.FromMinutes(0.5);
binding.SendTimeout = TimeSpan.FromMinutes(0.5);
// Compose URIs
Uri uriBase = new Uri(baseAddress);
Uri uri = new Uri(baseAddress + something);
Uri uriMex = new Uri(baseAddress + something + "/mex");
// Create End Points
SomeHost = new CustomServiceHost(typeof(TestService), uriBase);
SomeHost.AddServiceEndpoint(typeof(ITestService), binding, uri);
SomeHost.AddServiceEndpoint(typeof(IMetadataExchange), binding, uriMex);
// Open the ServiceHost
SomeHost.Open();
Now you should see you service dying after 30sec.
I want to create WCF client directly from code:
var binding = new BasicHttpBinding();
var myEndpoint = new EndpointAddress("http://localhost/acquisition/production.svc");
var myChannelFactory = new ChannelFactory<IProduction>(binding, myEndpoint);
proxy = myChannelFactory.CreateChannel();
The problem is that following code throws exception:
There was no endpoint listening at.
But when add reference do WCF test client, service is discovered properly and can be invoked withouy any errors:
Why manual endpoint doesn't work?
I dont have much knowledge on WCF. I have a WPF tablet application using WCF service to communicate with another instance of WPF application on other tablet.
WPF application places a pull request from other tablet's database via WCF service. This WCF service on the tablet fetches the data from database and sends it over TCP back to the requesting application. Same happens vice versa. Hence the synchronization is achieved. It happens over WiFi interface.
private const string WCFSERVICE_URL = "net.tcp://{0}:{1}/SynchronizeService"
Some code where we configure the client:
private DrillSynchronizeClient CreateConfigureClient(DrillNetInfo Drill)
{
DrillSynchronizeClient synchClient = new DrillSynchronizeClient();
string endpointUrl = String.Format(WCFSERVICE_URL, Drill.Ip, wcfServiceNetworkPort);
EndpointAddress serviceAddress = new EndpointAddress(endpointUrl);
NetTcpBinding netTcpBinding = new NetTcpBinding();
netTcpBinding.Security.Mode = SecurityMode.None;
netTcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
netTcpBinding.OpenTimeout = new TimeSpan(0, 5, 0);
netTcpBinding.CloseTimeout = new TimeSpan(0, 5, 0);
netTcpBinding.SendTimeout = new TimeSpan(0, 5, 0);
netTcpBinding.ReceiveTimeout = new TimeSpan(0, 5, 0);
netTcpBinding.MaxBufferPoolSize = int.MaxValue;
netTcpBinding.MaxBufferSize = int.MaxValue;
netTcpBinding.MaxReceivedMessageSize = int.MaxValue;
synchClient.Endpoint.Address = serviceAddress;
synchClient.Endpoint.Binding = netTcpBinding;
return synchClient;
}
This works fine when there is not internet connection available on these tablets.
When tablets are connected to internet via internet USB dongle, this synchronization stops working. Is the WCF trying to use the internet adapter(dongle) to resolve the WCF service IP address endpoint ?? Not sure, how to bind the WCF service to use only WLAN interface for communication.
Also please let me know where to specify/bind the source interface IP address to use when calling WCF request.
Thanks.
I use a third-party server written in Java.
WSDL is taken with the style of rpc/literal.
Connection to the service is initialized as follows:
private static MLPortChannel GetMerlionClient()
{
BasicHttpsBinding binding = new BasicHttpsBinding(BasicHttpsSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
binding.MaxReceivedMessageSize = 4096000;
EndpointAddress adress = new EndpointAddress(new Uri(#"https://apitest.merlion.com/rl/mlservice3"));
ChannelFactory<MLPortChannel> factory = new ChannelFactory<MLPortChannel>(binding, adress);
factory.Credentials.UserName.UserName = mlLogin;
factory.Credentials.UserName.Password = mlPassword;
return factory.CreateChannel();
}
It is works correctly only for one method and returns the correct data type and the data.
When I call other methods, they returns error as:
"Can not convert an object of type " ... MLService3RLTest.CatalogResult [] " of the type " ... MLService3RLTest.ShipmentDatesResult []"
In this example return type must be ShipmentDatesResult[].
I tested the service via special tool. All requests and responses is correct and returned correct XML.
What may be the cause of this error? Perhaps something needs to be configured for SOAP service. Maybe some magic option with right value?
If, instead of referring to the service, make a web link which uses the technology of web services .Net FrameWork 2.0 what works
var client = new WpfApplication1.com.merlion.apitest.MLService();
var myCredentials = new System.Net.NetworkCredential(Логин, Пароль);
// Create a webrequest with the specified URL.
var url = "https://apitest.merlion.com/rl/mlservice3";;
client.Credentials = myCredentials.GetCredential(new Uri(url), "Basic");
textBox.AppendText(client.helloWorld("Привет"));
var ответ = client.getCatalog("N1");
var массив = new string[] { "" };
var rz = client.getItems("N10100", массив, "", 0, 2, "");
add
client.PreAuthenticate = true;
I have an application which consumes a WCF web service, i log in to said service using credentials supplied by the company who maintain the service.
This is the code I created for binding the service.
I used svcutil.exe to generate a ClientSearchService.cs file and imported it into the project
BasicHttpBinding myBinding = new BasicHttpBinding();
myBinding.Name = "BasicHttpBinding_IClientSearch";
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
myBinding.MaxBufferSize = 524288;
myBinding.MaxBufferPoolSize = 524288;
myBinding.MaxReceivedMessageSize = 524288;
myBinding.ReaderQuotas.MaxDepth = 32;
myBinding.ReaderQuotas.MaxArrayLength = 524288;
myBinding.ReaderQuotas.MaxStringContentLength = 524288;
myBinding.Security.Mode = BasicHttpSecurityMode.TransportWithMessageCredential;
EndpointAddress endPointAddress = new EndpointAddress(serviceEndPointAddress);
ClientSearchClient myClient = new ClientSearchClient(myBinding, endPointAddress);
myClient.ClientCredentials.UserName.UserName = userName;
myClient.ClientCredentials.UserName.Password = userPass;
var request = new schemas.advancedcheck.co.uk.DriverChecksRequest();
request.FromDate = new DateTime(2014, 1, 1);
request.ToDate = DateTime.Now;
var response = myClient.GetDriverChecks(request);
If i execute this in a full trust environment i have no issues and the data I expect to see is returned successfully, however, where the code will be hosted will be a partial trust enviroment and when ran in a partial trust enviroment it throws this error:
The Binding with name BasicHttpBinding_IClientSearch failed validation because it contains a BindingElement with type System.ServiceModel.Channels.TransportSecurityBindingElement which is not supported in partial trust. Consider using BasicHttpBinding or WSHttpBinding, or hosting your application in a full-trust environment.
is there another method i can use to consume this web service in a partial trust enviroment?