Retry web service call if authentication failure requires re-login
I'm consuming a web service from C#, and the web service requires a login call and then uses cookie sessions. The web service will time out sessions after a certain timeframe, after which the client will have to re-login. I'd like to find a way to automatically catch the soap fault the service sends back in this scenario, and handle it by re-logging in and then retrying the previously attempted call.
I would prefer to do this somehow automatically for all the web service methods i开发者_JS百科n question, rather than having to manually wrap the calls with the retry logic.
Suggestions?
To avoid a similar issue in the past I actually "pinged" the service occasionally (I had control over the service at other end and created a very light-wight "ping" method but even if there is something simple you can use that would not constitute a denial of service!)
I think I pinged every 2 to 5 minutes or so, it would depend on the web service config etc... That way the authentication issue never really happened and I did not need to do the funky auto re-login thing :-)
-- otherwise... --
If you do need to do the re-login I would be wrapping the whole thing in an interface, this is good practice anyway with web-services, can stub them out etc. Design a class with utility methods to handle the logging in, you will find it hard to get around not re-typing a lot of calls but that's just the way it is!
Example....
public interface ISomeService
{
string Method1();
string Method2();
}
public class ReLoginWebService : ISomeService
{
readonly WebServiceProxy _proxy;
string _username;
string _password;
public ReLoginWebService(string username, string password)
{
_username = username;
_password = password;
_proxy = new WebServiceProxy();
Login();
}
public string Method1()
{
try
{
_proxy.Method1();
}
catch (Exception exp) // filter appropriately...
{
// if its a login error...
if (Login())
_proxy.Method1();
else
throw;
}
return "";
}
public string Method2()
{
try
{
_proxy.Method2();
}
catch (Exception exp) // filter appropriately...
{
// if its a login error...
if (Login())
_proxy.Method2();
else
throw;
}
return "";
}
protected bool Login()
{
return true; // i.e. success
}
}
I would recommend looking at the AspectF library where I have tried to solve such retry problems. You can do:
AspectF.Define.Retry(() => client.TheRealMethod(), () => login.DoLoginAgain());
Take a look at this, it makes coding such retry, error handling, logging etc a cleaner.
http://www.codeproject.com/KB/library/DotNetMQ.aspx
精彩评论