Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I implement ExecuteAsync with RestSharp on Windows Phone 7?

I'm attempting to use the documentation on the RestSharp GitHub wiki to implement calls to my REST API service but I'm having an issue with the ExecuteAsync method in particular.

Currently my code looks like this for the API class:

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

I'm aware this slightly deviates from what is on the GitHub page but I'm using this with WP7 and believe the example is for C# hence the usage of the ExecuteAsync method.

My problem is with what the ExecuteAsync command should contain. I can't use return response.Data because I'm warned:

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

Does anyone have any insight on how to fix this or a tutorial that may assist?

like image 451
joshcollie Avatar asked Apr 14 '12 12:04

joshcollie


People also ask

What is RestSharp used for?

RestSharp is a comprehensive, open-source HTTP client library that works with all kinds of DotNet technologies. It can be used to build robust applications by making it easy to interface with public APIs and quickly access data without the complexity of dealing with raw HTTP requests.

What is ExecuteAsync C#?

ExecuteAsync(MergeOption) Asynchronously executes the object query with the specified merge option. ExecuteAsync(MergeOption, CancellationToken) Asynchronously executes the object query with the specified merge option.


3 Answers

Old question but if you are using C# 5 you can have a generic execute class by creating a TaskCompleteSource that resturns a Task of T. Your code could look like this:

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

And use it like this:

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
    }
like image 192
Gusten Avatar answered Oct 22 '22 19:10

Gusten


As an alternative (or complement) to the fine answer by Gusten. You can use ExecuteAsync. This way you do not manually have to handle TaskCompletionSource. Note the async keyword in the signature.

Update: As of 106.4.0 ExecuteTaskAsync is obsolete. Since 104.2 you should use ExecuteAsync instead:

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.ExecuteAsync<T>(request);
    return response.Data;
}

Old Answer:

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); // Now obsolete
    return response.Data;
}
like image 33
smoksnes Avatar answered Oct 22 '22 18:10

smoksnes


Your code should look something like this:

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

I added two methods, so you can check what you want (string content from the response body, or a deserialized class represented here by MyClass)

like image 32
Pedro Lamas Avatar answered Oct 22 '22 17:10

Pedro Lamas