【问题标题】:How should I implement ExecuteAsync with RestSharp on Windows Phone 7?我应该如何在 Windows Phone 7 上使用 RestSharp 实现 ExecuteAsync?
【发布时间】:2012-04-14 12:48:36
【问题描述】:

我正在尝试使用 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

有没有人对如何解决这个问题有任何见解或可能有帮助的教程?

【问题讨论】:

    标签: c# api windows-phone-7 rest restsharp


    【解决方案1】:

    老问题,但如果您使用 C# 5,则可以通过创建返回 T 任务的 TaskCompleteSource 来获得通用执行类。您的代码可能如下所示:

    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
        }
    

    【讨论】:

    • 我的案例需要一个字符串响应。但这条线真的帮了我:client.ExecuteAsync(request, (response) => taskCompletionSource.SetResult(response.Data));我不确定如何直接返回响应而不是之前使用回调,这就是要走的路。如果有人想使用它,只需将 respon.Data 与 response.Content 交换并从任何地方删除 T
    • 我不得不问 - 你如何让它超过 NotYetExecuted 状态?今天一直在尝试使用此示例,但无法获得任何结果。非常感谢任何帮助。
    【解决方案2】:

    您的代码应如下所示:

    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表示的反序列化类)

    【讨论】:

    • 您的示例也有相同的语法错误并且无法编译。 ExecuteAsync的第二个参数是Action&lt;RestResponse&gt;,所以不能在里面使用return
    • 对不起,我已经修复了示例,请立即尝试(请注意:方法是异步的,因此您不能直接返回它,除非您使用 .NET Async Task )
    • 可以帮我如何使用 ExecuteAndGetMyClass 吗?
    • 当前上下文中不存在回调
    • 尝试此解决方案时,我得到:错误 CS1593 Delegate 'Action' does not take 1 arguments
    【解决方案3】:

    作为fine answer 的替代(或补充)Gusten。您可以使用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;
    }
    

    【讨论】:

    • 这是我一直在寻找的答案...谢谢!比其他解决方案更直接(尽管不一定是 OP 所追求的)
    • 如何从该方法的输出中访问StatusCode
    • 我不确定我是否理解。上面的例子根本没有使用StatusCode。您可以返回response,而不是返回response.Data。然后你需要将返回类型更改为Task&lt;IRestResponse&lt;T&gt;&gt;
    【解决方案4】:

    或者更准确地说是这样的:

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

    【讨论】:

      【解决方案5】:

      下面的工作完成了

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

      【讨论】:

      • 这在函数调用中是如何实现的?是var myclass = await apiService.ExecuteAsync&lt;MyClass&gt;(request);吗?
      【解决方案6】:

      由于public static RestRequestAsyncHandle ExecuteAsync(this IRestClient client, IRestRequest request, Action&lt;IRestResponse&gt; callback) 已被弃用,您应该改用public Task&lt;IRestResponse&gt; ExecuteAsync(IRestRequest request, CancellationToken token = default)

      以下代码

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

      应该改为

      await client.ExecuteAsync(request).ContinueWith(task => callback(task.Result.Content));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多