web-dev-qa-db-fra.com

Comment dois-je implémenter ExecuteAsync avec RestSharp sur Windows Phone 7?

J'essaie d'utiliser la documentation sur le wiki RestSharp GitHub pour implémenter les appels à mon REST API mais j'ai un problème avec la méthode ExecuteAsync en particulier .

Actuellement, mon code ressemble à ceci pour la classe API:

public class HarooApi
{
    const string BaseUrl = "https://domain.here";

    readonly string _accountSid;
    readonly string _secretKey;

    public HarooApi(string accountSid, string secretKey)
    {
        _accountSid = accountSid;
        _secretKey = secretKey;
    }

    public T Execute<T>(RestRequest request) where T : new()
    {
        var client = new RestClient();
        client.BaseUrl = BaseUrl;
        client.Authenticator = new HttpBasicAuthenticator(_accountSid, _secretKey);
        request.AddParameter("AccountSid", _accountSid, ParameterType.UrlSegment);
        client.ExecuteAsync<T>(request, (response) =>
        {
            return response.Data;
        });
    }
}

Je suis conscient que cela s'écarte légèrement de ce qui est sur la page GitHub, mais je l'utilise avec WP7 et je crois que l'exemple est pour C #, d'où l'utilisation de la méthode ExecuteAsync.

Mon problème est avec ce que la commande ExecuteAsync devrait contenir. Je ne peux pas utiliser return response.Data parce que je suis prévenu:

'System.Action<RestSharp.RestResponse<T>,RestSharp.RestRequestAsyncHandle>' returns void, a return keyword must not be followed by an object expression

Quelqu'un at-il une idée de la façon de résoudre ce problème ou d'un didacticiel qui peut vous aider?

27
joshcollie

Votre code devrait ressembler à ceci:

public class HarooApi
{
    const string BaseUrl = "https://domain.here";

    readonly string _accountSid;
    readonly string _secretKey;

    public HarooApi(string accountSid, string secretKey)
    {
        _accountSid = accountSid;
        _secretKey = secretKey;
    }

    public void ExecuteAndGetContent(RestRequest request, Action<string> callback)
    {
        var client = new RestClient();
        client.BaseUrl = BaseUrl;
        client.Authenticator = new HttpBasicAuthenticator(_accountSid, _secretKey);
        request.AddParameter("AccountSid", _accountSid, ParameterType.UrlSegment);
        client.ExecuteAsync(request, response =>
        {
            callback(response.Content);
        });
    }

    public void ExecuteAndGetMyClass(RestRequest request, Action<MyClass> callback)
    {
        var client = new RestClient();
        client.BaseUrl = BaseUrl;
        client.Authenticator = new HttpBasicAuthenticator(_accountSid, _secretKey);
        request.AddParameter("AccountSid", _accountSid, ParameterType.UrlSegment);
        client.ExecuteAsync<MyClass>(request, (response) =>
        {
            callback(response.Data);
        });
    }
}

J'ai ajouté deux méthodes, vous pouvez donc vérifier ce que vous voulez (contenu de chaîne du corps de réponse, ou une classe désérialisée représentée ici par MyClass)

25
Pedro Lamas

Ancienne question, mais si vous utilisez C # 5, vous pouvez avoir une classe d'exécution générique en créant un TaskCompleteSource qui restitue une tâche de T. Votre code pourrait ressembler à ceci:

public Task<T> ExecuteAsync<T>(RestRequest request) where T : new()
    {
        var client = new RestClient();
        var taskCompletionSource = new TaskCompletionSource<T>();
        client.BaseUrl = BaseUrl;
        client.Authenticator = new HttpBasicAuthenticator(_accountSid, _secretKey);
        request.AddParameter("AccountSid", _accountSid, ParameterType.UrlSegment);
        client.ExecuteAsync<T>(request, (response) => taskCompletionSource.SetResult(response.Data));
        return taskCompletionSource.Task;
    }

Et utilisez-le comme ceci:

private async Task DoWork()
    {
        var api = new HarooApi("MyAcoountId", "MySecret");
        var request = new RestRequest();
        var myClass = await api.ExecuteAsync<MyClass>(request);

        // Do something with myClass
    }
49
Gusten

Comme alternative (ou complément) à la bonne réponse par Gusten . Vous pouvez utiliser ExecuteTaskAsync. De cette façon, vous n'avez pas à gérer manuellement TaskCompletionSource. Notez le mot clé async dans la signature.

public async Task<T> ExecuteAsync<T>(RestRequest request) where T : new()
{
    var client = new RestClient();
    client.BaseUrl = BaseUrl;
    client.Authenticator = new HttpBasicAuthenticator(_accountSid, _secretKey);
    request.AddParameter("AccountSid", _accountSid, ParameterType.UrlSegment);
    IRestResponse<T> response = await client.ExecuteTaskAsync<T>(request);
    return response.Data;
}
20
smoksnes

Ou plus précisément comme ceci:

    public async Task<IRestResponse<T>> ExecuteAsync<T>(IRestRequest request) where T : class, new()
    {
        var client = new RestClient(_settingsViewModel.BaseUrl);

        var taskCompletionSource = new TaskCompletionSource<IRestResponse<T>>();
        client.ExecuteAsync<T>(request, restResponse =>
        {
            if (restResponse.ErrorException != null)
            {
                const string message = "Error retrieving response.";
                throw new ApplicationException(message, restResponse.ErrorException);
            }
            taskCompletionSource.SetResult(restResponse);
        });

        return await taskCompletionSource.Task;
    }
7
Per Schondell

Ce qui suit a fait le travail

public async Task<IRestResponse<T>> ExecuteAsync<T>(IRestRequest request) where T : class, new()
{
    var client = new RestClient
    {
        BaseUrl = _baseUrl,
        Authenticator = new HttpBasicAuthenticator(_useraname, _password),
        Timeout = 3000,
    };

    var tcs = new TaskCompletionSource<T>();
    client.ExecuteAsync<T>(request, restResponse =>
    {
        if (restResponse.ErrorException != null)
        {
            const string message = "Error retrieving response.";
            throw new ApplicationException(message, restResponse.ErrorException);
        }
        tcs.SetResult(restResponse.Data);
    });

    return await tcs.Task as IRestResponse<T>;

}
1
ageroh