Проблема с переводом функции делегата с C# на vb.net для использования с Google OAuth 2
Я пытался перевести пример Google OAuth 2 с C# на Vb.net для проекта сотрудника. У меня есть в конце вопросов перевод следующих методов:
private OAuth2Authenticator<WebServerClient> CreateAuthenticator()
{
// Register the authenticator.
var provider = new WebServerClient(GoogleAuthenticationServer.Description);
provider.ClientIdentifier = ClientCredentials.ClientID;
provider.ClientSecret = ClientCredentials.ClientSecret;
var authenticator =
new OAuth2Authenticator<WebServerClient>(provider, GetAuthorization) { NoCaching = true };
return authenticator;
}
private IAuthorizationState GetAuthorization(WebServerClient client)
{
// If this user is already authenticated, then just return the auth state.
IAuthorizationState state = AuthState;
if (state != null)
{
return state;
}
// Check if an authorization request already is in progress.
state = client.ProcessUserAuthorization(new HttpRequestInfo(HttpContext.Current.Request));
if (state != null && (!string.IsNullOrEmpty(state.AccessToken) || !string.IsNullOrEmpty(state.RefreshToken)))
{
// Store and return the credentials.
HttpContext.Current.Session["AUTH_STATE"] = _state = state;
return state;
}
// Otherwise do a new authorization request.
string scope = TasksService.Scopes.TasksReadonly.GetStringValue();
OutgoingWebResponse response = client.PrepareRequestUserAuthorization(new[] { scope });
response.Send(); // Will throw a ThreadAbortException to prevent sending another response.
return null;
}
Основной проблемой является эта линия:
var authenticator = new OAuth2Authenticator<WebServerClient>(provider, GetAuthorization) { NoCaching = true };
Сигнатура метода читается так, как для этой конкретной строки:
Public Sub New(tokenProvider As TClient, authProvider As System.Func(Of TClient, DotNetOpenAuth.OAuth2.IAuthorizationState))
Мое понимание функций делегатов в VB.net не самое лучшее. Тем не менее, я прочитал всю документацию MSDN и другие соответствующие ресурсы в Интернете, но я все еще застрял в том, как перевести эту конкретную строку.
До сих пор все мои попытки приводили либо к ошибке приведения (см. Ниже), либо к отсутствию вызова GetAuthorization.
Кодекс (vb.net на.net 3.5)
Private Function CreateAuthenticator() As OAuth2Authenticator(Of WebServerClient)
' Register the authenticator.
' Register the authenticator.
Dim provider = New WebServerClient(GoogleAuthenticationServer.Description, oauth.ClientID, oauth.ClientSecret)
'GetAuthorization isn't called
'Dim authenticator = New OAuth2Authenticator(Of WebServerClient)(provider, AddressOf GetAuthorization) With {.NoCaching = True}
'This works, but results in type error
Dim authDelegate As Func(Of WebServerClient, IAuthorizationState) = AddressOf GetAuthorization
Dim authenticator = New OAuth2Authenticator(Of WebServerClient)(provider, authDelegate) With {.NoCaching = True}
'This works, but results in type error
'Dim authenticator = New OAuth2Authenticator(Of WebServerClient)(provider, GetAuthorization(provider)) With {.NoCaching = True}
'GetAuthorization isn't called
'Dim authenticator = New OAuth2Authenticator(Of WebServerClient)(provider, New Func(Of WebServerClient, IAuthorizationState)(Function(c) GetAuthorization(c))) With {.NoCaching = True}
'Dim authenticator = New OAuth2Authenticator(Of WebServerClient)(provider, New Func(Of WebServerClient, IAuthorizationState)(AddressOf GetAuthorization)) With {.NoCaching = True}
Return authenticator
End Function
Private Function GetAuthorization(arg As WebServerClient) As IAuthorizationState
' If this user is already authenticated, then just return the auth state.
Dim state As IAuthorizationState = AuthState
If (Not state Is Nothing) Then
Return state
End If
' Check if an authorization request already is in progress.
state = arg.ProcessUserAuthorization(New HttpRequestInfo(HttpContext.Current.Request))
If (state IsNot Nothing) Then
If ((String.IsNullOrEmpty(state.AccessToken) = False Or String.IsNullOrEmpty(state.RefreshToken) = False)) Then
' Store Credentials
HttpContext.Current.Session("AUTH_STATE") = state
_state = state
Return state
End If
End If
' Otherwise do a new authorization request.
Dim scope As String = AnalyticsService.Scopes.AnalyticsReadonly.GetStringValue()
Dim _response As OutgoingWebResponse = arg.PrepareRequestUserAuthorization(New String() {scope})
' Add Offline Access and forced Approval
_response.Headers("location") += "&access_type=offline&approval_prompt=force"
_response.Send() ' Will throw a ThreadAbortException to prevent sending another response.
Return Nothing
End Function
Ошибка приведения
Server Error in '/' Application.
Unable to cast object of type 'DotNetOpenAuth.OAuth2.AuthorizationState' to type 'System.Func`2[DotNetOpenAuth.OAuth2.WebServerClient,DotNetOpenAuth.OAuth2.IAuthorizationState]'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidCastException: Unable to cast object of type 'DotNetOpenAuth.OAuth2.AuthorizationState' to type 'System.Func`2[DotNetOpenAuth.OAuth2.WebServerClient,DotNetOpenAuth.OAuth2.IAuthorizationState]'.
Я провел большую часть дня на этом, и это начинает сводить меня с ума. Помощь очень ценится.
ОБНОВИТЬ
Я не упомянул, что перепробовал все доступные онлайн конвертации C# в VB.net. Все это приводит к следующему преобразованию рассматриваемой строки:
Dim authenticator = New OAuth2Authenticator(Of WebServerClient)(provider, AddressOf GetAuthorization) With {.NoCaching = True}
В результате метод GetAuthorization не вызывается.
2 ответа
Строка кода, которую придумал конвертер, а также другие ваши решения, которые не выдают исключений, все выглядят хорошо. Если при преобразовании этого строкового кода возникнут проблемы, возникнет исключение или ошибка. Это означало бы, что проблема лежит в другом месте кода, возможно, в OAuth2Authenticator(T)
конструктор.
Может ли ваш коллега просто использовать ссылку на библиотеку (бинарную или проектную), чтобы вам не пришлось конвертировать код?
Для перевода кода с одного языка на другой старайтесь использовать отличный инструмент SharpDevelop. Этот инструмент является бесплатной альтернативой MS VS 2008, и вы можете переводить между языками C#, VB.NET, IronPython и Boo.