我正在尝试使用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
有没有人对如何解决此问题或可能有帮助的教程有任何见解?
答案 0 :(得分:48)
老问题但是如果你正在使用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
}
答案 1 :(得分:25)
您的代码应如下所示:
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
表示的反序列化类)
答案 2 :(得分:17)
作为fine answer Gusten的替代(或补充)。您可以使用ExecuteTaskAsync
。这样您就不必手动处理TaskCompletionSource
。请注意签名中的async
关键字。
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;
}
答案 3 :(得分:7)
或更准确地说是这样:
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;
}
答案 4 :(得分:1)
以下完成了工作
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>;
}
答案 5 :(得分:1)
自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));