Как реализовать ExecuteAsync с RestSharp на Windows Phone 7?

Я пытаюсь использовать документацию на RestSharp GitHub wiki для реализации вызовов моя служба REST API, но у меня проблема, в частности, с методом ExecuteAsync.

В настоящее время мой код для класса 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;
        });
    }
}

Я знаю, что это немного отличается от того, что есть на странице GitHub, но я использую это с WP7 и считаю, что пример предназначен для C #, поэтому используется метод ExecuteAsync.

Моя проблема заключается в том, что должна содержать команда ExecuteAsync. Я не могу использовать return response.Data, потому что меня предупредили:

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

Кто-нибудь знает, как это исправить, или учебник, который может помочь?


person joshcollie    schedule 14.04.2012    source источник


Ответы (6)


Ваш код должен выглядеть примерно так:

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

Я добавил два метода, чтобы вы могли проверить, что хотите (строковое содержимое из тела ответа или десериализованный класс, представленный здесь MyClass)

person Pedro Lamas    schedule 14.04.2012
comment
Ваш образец также имеет ту же синтаксическую ошибку и не компилируется. Второй параметр ExecuteAsync — это Action<RestResponse>, поэтому в нем нельзя использовать return. - person nemesv; 14.04.2012
comment
Извините за это, я исправил пример, попробуйте сейчас (и обратите внимание: методы асинхронные, поэтому вы не можете напрямую вернуть его, если не используете асинхронную задачу .NET) - person Pedro Lamas; 14.04.2012
comment
Может ли кто-нибудь помочь мне, как использовать ExecuteAndGetMyClass? - person Nil Pun; 03.09.2012
comment
обратный вызов не существует в текущем контексте - person Parth Savadiya; 21.10.2015
comment
При попытке этого решения я получаю: Ошибка CS1593 Делегат «Действие‹IRestResponse, RestRequestAsyncHandle›» не принимает 1 аргумент - person Kevin Burton; 11.12.2019

Старый вопрос, но если вы используете С# 5, вы можете иметь общий класс выполнения, создав TaskCompleteSource, который возвращает Task of T. Ваш код может выглядеть так:

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

И используйте это так:

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
    }
person Gusten    schedule 10.02.2014
comment
Мне нужен был строковый ответ для моего случая. Но мне очень помогла эта строчка: client.ExecuteAsync‹T›(request, (response) =› taskCompletionSource.SetResult(response.Data)); Я не был уверен, как вернуть ответ напрямую вместо использования обратного вызова, и это путь. Если кто-то хочет использовать это, просто замените respone.Data на response.Content и удалите T везде. - person Alek Arsovski; 30.06.2015
comment
Я должен спросить - как вы получаете статус NotYetExecuted? Пробовал сегодня с этим образцом и не получил никаких результатов. Любая помощь высоко ценится. - person Richard Griffiths; 30.03.2016

В качестве альтернативы (или дополнения) к отличному ответу от Густен. Вы можете использовать ExecuteAsync. Таким образом, вам не нужно вручную обрабатывать TaskCompletionSource. Обратите внимание на ключевое слово async в подписи.

Обновление: начиная с 106.4.0 ExecuteTaskAsync устарело. Поскольку 104.2 вместо этого следует использовать ExecuteAsync:

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

Старый ответ:

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;
}
person smoksnes    schedule 07.12.2017
comment
это ответ, который я искал ... спасибо! Гораздо проще, чем другие решения (хотя и не обязательно то, что было после ОП) - person reidLinden; 05.01.2018
comment
Как получить доступ к StatusCode из вывода этого метода? - person Mehdi Dehghani; 17.04.2018
comment
Я не уверен, что понимаю. В приведенном выше примере StatusCode вообще не используется. Вместо возврата response.Data вы можете вернуть response. Затем вам нужно изменить тип возврата на Task<IRestResponse<T>>. - person smoksnes; 17.04.2018

Или точнее вот так:

    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;
    }
person Per Schondell    schedule 29.03.2016

Следующее сделал работу

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

}
person ageroh    schedule 06.03.2016
comment
Как это реализовано в вызове функции? это var myclass = await apiService.ExecuteAsync<MyClass>(request);? - person DogEatDog; 08.09.2017

Поскольку public static RestRequestAsyncHandle ExecuteAsync(this IRestClient client, IRestRequest request, Action<IRestResponse> callback) устарел, вам следует вместо этого использовать public Task<IRestResponse> ExecuteAsync(IRestRequest request, CancellationToken token = default).

Следующий код

client.ExecuteAsync(request, response => { callback(response.Content); });

Вместо этого должен стать

await client.ExecuteAsync(request).ContinueWith(task => callback(task.Result.Content));
person Chris Stillwell    schedule 24.06.2020