2012-04-14 18 views
18

Sto tentando di utilizzare la documentazione su RestSharp GitHub wiki per implementare le chiamate al mio servizio API REST ma sto avendo un problema con il metodo ExecuteAsync in particolare.Come devo implementare ExecuteAsync con RestSharp su Windows Phone 7?

Attualmente il mio codice è simile per 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; 
     }); 
    } 
} 

Sono consapevole questo si discosta leggermente da quello che è sulla pagina GitHub, ma sto usando questo con WP7 e credere l'esempio è per C# quindi l'uso del metodo ExecuteAsync.

Il mio problema è con cosa deve contenere il comando ExecuteAsync. Non posso usare return response.Data perché sto messo in guardia:

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

Qualcuno ha una visione chiara su come riparare questo o un tutorial che può aiutare?

risposta

22

Il codice dovrebbe essere simile a questo:

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); 
     }); 
    } 
} 

ho aggiunto due metodi, in modo da poter controllare ciò che vuole (il contenuto della stringa dal corpo di risposta, o di una classe deserializzato qui rappresentata da MyClass)

+0

Anche l'esempio ha lo stesso errore di sintassi e non viene compilato. Il secondo parametro di 'ExecuteAsync' è un 'Action ' quindi non può usare 'return' in esso. – nemesv

+0

Mi spiace, ho corretto l'esempio, per favore provalo ora (e per favore nota: i metodi sono asincroni, quindi non puoi restituirlo direttamente, a meno che non usi l'attività Async .NET) –

+8

Qualcuno potrebbe aiutarmi utilizzare l'ExecuteAndGetMyClass? –

36

vecchia questione, ma se si sta utilizzando C# 5 si può avere una classe generica esecuzione creando un TaskCompleteSource che Resturns una Task di T. il codice potrebbe essere la seguente:

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; 
    } 

e usarlo in questo modo:

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 
    } 
+1

Questa risposta è accurata per WP8 + e per i giorni moderni ... –

+0

Avevo bisogno di una risposta stringa per il mio caso. Ma questa linea mi ha davvero aiutato: client.ExecuteAsync (request, (response) => taskCompletionSource.SetResult (response.Data)); Non ero sicuro di come restituire la risposta direttamente invece di usare una richiamata prima e questa è la strada da percorrere. Se qualcuno vuole usarlo scambia il respone.Data con response.Content e rimuovi la T da ovunque –

+0

Devo chiederti: come fai a superare lo stato di NotYetExecuted?Ho provato oggi con questo campione e non posso ottenere alcun risultato. Qualsiasi aiuto molto apprezzato. –

1

Di seguito ha fatto il lavoro

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>; 

} 
+0

Come viene implementato nella chiamata di funzione? è 'var myclass = attendi apiService.ExecuteAsync (richiesta);'? – DogEatDog

+0

Sì, si potrebbe fare in questo modo – ageroh

5

O più precisamente in questo modo:

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; 
    } 
3

In alternativa (o complementare) alla fine answer di Gusten. È possibile utilizzare ExecuteTaskAsync. In questo modo non devi gestire manualmente TaskCompletionSource. Prendere nota della parola chiave async nella firma.

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; 
} 
+0

questa è la risposta che stavo cercando ... grazie! Molto più semplice delle altre soluzioni (anche se non necessariamente ciò che l'OP cercava) – reidLinden