は私がうまく機能している解決策を考え出しました。
私は2つの引数Funcと私の 認証オブジェクトへの参照を受け付ける静的メソッドを作成しました。 Authenticationオブジェクトは再認証が可能で、API呼び出しを行うための認証情報を保持します。 1つのアカウントで複数のAuthenticatorを別々の認証トークンで使用する必要がないため、refを使用しましたが、複数のアカウントを同時にサポートできる必要があったため、静的にすることはできませんでした。
public static string ReauthenticateOn401(
Func<Authenticator, string> method,
ref Authenticator authenticator)
{
if (method == null)
throw new ArgumentNullException("action");
if (authenticator == null)
throw new ArgumentNullException("authenticator");
int attempts_remaining = 2;
bool reauth_attempted = false;
while (attempts_remaining > 0)
{
try
{
return method(authenticator);
}
catch (WebException e)
{
if (e.Response != null && reauth_attempted == false)
{
if (((HttpWebResponse)e.Response).StatusCode == HttpStatusCode.Unauthorized)
{
authenticator.GetAuthToken();
reauth_attempted = true;
attempts_remaining--;
}
else
{
throw;
}
}
else
{
throw;
}
}
}
throw new Exception("The ReauthenticateOn401 method failed to return a response or catch/throw an exception. The log flowed outside the while loop (not expected to be possible) and is generating this generic exception");
}
次に、APIからデータを要求するためのクラスが異なります。ここでは、クラスのインスタンス化時に_authenticatorがクラスに渡されるようなものがあります。
string json = Authenticator.ReauthenticateOn401((authenticator) =>
{
string apiUrl = "http:/blahblahblah.api.com"
HttpWebRequest request = WebRequest.Create(apiUrl) as HttpWebRequest;
//Add headers, or adjust the body as necessary for your API
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
return reader.ReadToEnd();
}
}, ref _authenticator);
美しさは、私は私がReathenticateOn401に好きなロジックに渡すことができるということであり、それは、メソッドを呼び出そうとした後、401を受信した場合は再認証します。さもなければ、それは成功するか、または私が次に処理できる例外をスローします。