check the availability of the WCF Web Service - wcf

I want to check the availability of the WCF web service i.c service is up or down through the C# code. How to achieve that?

When you call Client.Open if it is down that should throw an exception which you can trap.
What I prefer to do is implement a method which returns a boolean called Ping. The code basically just does return true; so it returns as quickly as possible. On the client side I call it and trap exceptions, if I get any then I know the web service is down.
You can extend the pattern to do things like PingCheckDB or PingCheckX which can do a fake/sample test run so you enable/disable functionality on the client based on what is available.

To elaborate on the previous answer: the only way to determine if a service is "available" is to first determine what you mean by "available". For instance, a service that depends on an external resource like a database may be perfectly available, but if the database cannot be accessed, then the service will be available but useless.
You should also ask what you are going to do with the information about availability. In particular, what would happen if you decided that the service was "available" yet, when you call it, you find that it is not really "available". An example would be if the above service was available and the database was available, but there was one particular stored procedure which would always fail. Is the service "available" in this case? How bad would it be if you indicated that it was available, but this one stored procedure failed?
In many cases, it's best to simply go ahead and make the calls to the web service, then handle any exceptions. If you've validated the parameters you're sending to the service, then, from the point of view of the end user, any failure of the service amounts to the service being unavailable.
It is not available to be successfully used, you see.

This is what I'm using and it works great. And ServiceController lives in namespace 'System.ServiceProcess' if you want to use a Using statement at the top to qualify it.
try
{
ServiceController sc = new ServiceController("Service Name", "Computer's IP Address");
Console.WriteLine("The service status is currently set to {0}",
sc.Status.ToString());
if ((sc.Status.Equals(ServiceControllerStatus.Stopped)) ||
(sc.Status.Equals(ServiceControllerStatus.StopPending)))
{
Console.WriteLine("Service is Stopped, Ending the application...");
Console.Read();
EndApplication();
}
else
{
Console.WriteLine("Service is Started...");
}
}
catch (Exception)
{
Console.WriteLine("Error Occurred trying to access the Server service...");
Console.Read();
EndApplication();
}

I use the following code. It's simple and works...
public bool IsServiceRunning()
{
try
{
System.Net.WebClient wc = new System.Net.WebClient();
string s = wc.DownloadString(new Uri("http://localhost:27777/whatever/services/GatherDataService?wsdl"));
}
catch (Exception ex)
{
return false;
}
return true;
}
just take your endpoint uri and add the ?wsdl

Related

How to call more than 1000 web APIs with a main API with very less response time

I have to implement MVC .Net Web api (say "Main" api) which includes two parts.
1) Database call to fetch the record.
2) And more than 1000s of another web api call(response time 100 ms on avg. for each) which will use records returned by above db call.
Also, the Main api will be called in every 3 seconds continuously. I tried implementing using async/await method but didn't find much progress and when trying to test it using Apache Benchmark tool, it throws timeout specified has expired error.
Is there any way to achieve this? Please suggest.
Code snippet
[HttpGet]
public async Task<string> doTaskasync()
{
TripDetails obj = new TripDetails();
GPSCoordinates objGPS = new GPSCoordinates();
try
{
/* uriArray Contains more than 1000 APIs which needs to be exectued. */
string[] uriArray = await dolongrunningtaskasync();
IEnumerable<Task<GPSCoordinates>> allTasks = uriArray .Select(u => GetLocationsAsync(u));
IEnumerable<GPSCoordinates> allResults = await Task.WhenAll(allTasks);
}
catch (Exception ex)
{
return ex.Message ;
}
return "success";
}
Ab.exe test
There is nothing wrong programmatically with your code - except that this is practically a DOS attack on the second (location) API. You should definitely add caching to avoid at least part of the 1000 api calls, especially if you call the main api often (as you wrote).
What I would do is to make the inner api calls a centralized operation instead of making these calls individually inside your web api method. For example you could use a central list for location api calls (tasks) that have been started (but not finished), and another list for results that have been already finished. Both list could be a concurrent dictionary by the unique urls you use for the location api calls.

How to tell whether Accounts.addEmail succeeded or failed, and if it failed, the reason why

I have a page where the user can type in a new email address and then this method attempts to add it to their account:
Meteor.methods({
add_new_email: function(address)
{
Accounts.addEmail(Meteor.userId(), address);
}
});
I'm using the accounts-password package in Meteor.
I'd like to give the user meaningful feedback after they try to add the new address, in particular if it failed why did it fail? I have looked at the docs but there doesn't seem to be any method to find out failure reason.
I know that I can count the user's email addresses before and after trying to add the new one, but that doesn't tell me if the address already belongs to another user, or if it's an existing address of the user's, or whatever is the failure reason.
Is there any way to find out the result of an API call like this?
You can read the information about what this method does here:
https://github.com/meteor/meteor/blob/master/packages/accounts-password/password_server.js#L847
As you can see, the method will fail only in one case:
The operation will fail if there is a different user with an email
only differing in case
Therefore if the method fails you can tell to the user that the email is already registered.
After experimenting some more, it seems that all I need to do is add a callback to my client when I call the method, and check there for an error. Any error is automatically returned to the callback.
Server:
Meteor.methods({
add_new_email: function(address)
{
Accounts.addEmail(Meteor.userId(), address);
}
});
Client:
Meteor.call('add_new_email', 'me#example.com', function(error){
if (error) console.log("got an error " + error.reason);
});
I had not realised that the error from the API would be passed up into my method. Meteor - it's always more clever than I expect!
Note also that you can use Meteor.Error in your methods to throw errors which will be passed up to client callbacks in exactly the same way, see the docs:
if (!Meteor.userId()) {
throw new Meteor.Error("not-authorized", "You must be signed in to write a new post");
}
I know I'm a bit late to the party but I ran into this problem today and found your post.
I needed to be able to tell on the server side whether it failed or not so what I did was put it in a try-catch like so:
let addSucceeded = false;
try{
Accounts.addEmail(user._id, newEmailAddress);
addSucceeded = true;
} catch(err) {}
console.log(addSucceeded);
Only if the Accounts.addEmail does not fail will addSucceeded be set to true. To make sure I don't run into the "fail because it replaced the same user's email address in a different case" scenario, I always toLowerCase() the email address when saving.

WCF Windows Service and Windows Store App Non-Meaningful Reply Error Message

I'm having a lot of problems getting tyres on the ground with Windows 8 Programming.
One problem is, I cannot install IIS as Windows 8 is giving me problems because I am dual booting it with 7. Any OS updates fail, including configuration changes such as adding IIS.
But anyway, to get around this, I decided to host a WCF service in a Windows Service with a TCP endpoint, and consume that service in my Store app. For inserts, it works, not a problem.
But when I go to retrieve some data (a very small data set - 3 records), the following error displays: 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.
I've Googled that error and it seems to be a common one - meaning it could be anything. But I am a total noob with WCF.
My code in the ViewModel is simply:
private async void PopulatePeople()
{
var people = await licenceBucketService.GetAllPersonsAsync();
FirstName = people.First().FirstName;
LastName = people.First().LastName;
}
The GetAllPersons method is:
public ObservableCollection<Person> GetAllPersons()
{
ObservableCollection<Person> people = null;
using (var context = new LicenceBucketContext())
{
people = new ObservableCollection<Person>(context.People);
}
return people;
}
The async version in the Reference.cs file looks like:
public System.Threading.Tasks.Task<System.Collections.ObjectModel.ObservableCollection<Win8UI.LicenceBucketService.Person>> GetAllPersonsAsync() {
return base.Channel.GetAllPersonsAsync();
}
Do any WCF gurus see my issue?

WCF WebApi, what is the correct way to handle IsThisTaken query?

I am in the process of writing a WCF webapi application and have a need to check whether an email address is taken or not. This needs to be a query the client-side code can do before attempting a PUT.
So, what I'm trying to do is use HEAD in conjunction with HTTP status codes. I am a little unsure how to go about doing that as it's a simple yes/no response which is required. So, I've used HttpResponseExceptions to return the relevant status code.
[WebInvoke(Method = "HEAD", UriTemplate = "{email}")]
[RequireAuthorisation]
public void IsEmailAddressTaken(string email)
{
if (!Regex.IsMatch(email, Regexes.EmailPattern))
{
throw new RestValidationFailureException("email", "invalid email address");
}
if (_repository.IsEmailAddressTaken(email))
{
throw new HttpResponseException(HttpStatusCode.OK);
}
throw new HttpResponseException(HttpStatusCode.NoContent);
}
This just doesn't "smell" right to me.
am I going about doing this kind of yes/no operation the right way?
My suggestion is to return a HttpResponseMessage instead of throwing exceptions.
Is your RestValidationFailureException being handled anywhere? If not, it will result in a 500 status code, which does not seem adequate.
I think it would be ok to just return OK for "exists" and 404 for "does not exist"

How to expose ErrorCode values?

I have web services written on WCF. I use request/response pattern and don't use FaultException. I return an error code in response contract as string. I need to expose error codes for clients in order to clients can handle exceptions. 
For example:
Var r = client.DoSomething();
Switch (r.ErrorCode)
{
Case ERROR_CODES.SomeCode:
//TODO:
}
Clients are WS-*, not only .Net.
UPDATE:
Sorry, my English is elementary. I've tried to explain in a different way.
When I use class File, I know that this class can throws some exceptions, for example, FileNotFoundException or DirectoryNotFoundException. If I create a File service How can I tell client that my service can returns "FileNotFound" or other error codes?
We generally try and use FaultContracts.
When we cannot we use a Response object that inherits from ResponseBase. ResponseBase has 2 properties, StatusCode and StatusMessage.
In your case ErrorCode, just add this property to your data contract.