在此处创建客户端和API请求的通用方法:
public class Client : IDisposable
{
private HttpClient _client;
private void CreateClient()
{
_client = new HttpClient();
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
_client.DefaultRequestHeaders.Add("KEY", token);
}
public void Dispose() => _client?.Dispose();
public enum Method { GET, POST, PUT, DELETE }
public HttpResponseMessage Request(string url, Method method, object data, HttpContent request)
{
if (data != null)
request = new StringContent(Serialize(data), Encoding.UTF8, "application/json");
switch (method)
{
case Method.POST: return _client.PostAsync(url, request).Result;
case Method.PUT: return _client.PutAsync(url, request).Result;
case Method.DELETE: return _client.DeleteAsync(url).Result;
default: return _client.GetAsync(url).Result;
}
}
public Task<HttpResponseMessage> RequestAsync(string url, Method method, object data, HttpContent request)
{
if (data != null)
request = new StringContent(Serialize(data), Encoding.UTF8, "application/json");
switch (method)
{
case Method.GET: return _client.GetAsync(url);
case Method.POST: return _client.PostAsync(url, request);
case Method.PUT: return _client.PutAsync(url, request);
case Method.DELETE: return _client.DeleteAsync(url);
default: return _client.GetAsync(url);
}
}
public string Post(string url, object data) =>
Request(url, Method.POST, data, null).Content.ReadAsStringAsync().Result;
public Task<HttpResponseMessage> PostAsync(string url, object data) =>
RequestAsync(url, Method.POST, data, null);
//UTILS
private static string Serialize(object data) =>
data == null
? string.Empty
: JsonConvert.SerializeObject(data, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
}
我正在尝试将这些方法调用到特定的类,以简化对客户的使用。例如,要为信用卡中的交易创建新的结帐:
public class Checkout : SDK
{
private static Client client;
public Checkout() => client = new Client();
public static async Task Credit(object data) =>
await client.PostAsync(url, data);
}
该请求需要基于一些模型安装,这些模型可以具有这种结构,而我试图以一种简单的方式生成它,如下所示:
public async Task Test()
{
var transaction = new Transaction
{
PaymentMethod = new PaymentMethod { Code = "1" },
Application = "Test",
Vendor = "Name",
Customer = new Customer
{
//Customer details...
},
Products = new List<TransactionProduct>
{
//Products...
}
};
var teste = Checkout.Credit(transaction);
Console.WriteLine(teste);
}
我得到的回报是:
System.Threading.Tasks.Task`1[System.Threading.Tasks.VoidTaskResult]
Id = 1, Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}"
我尝试为await
通话添加Checkout.Credit
,但得到:
CS0815 Test C# Cannot assign void to an implicitly-typed variable
使用一个简单的HttpClient请求进行单元测试就像一个魅力一样,但是我无法在我的项目结构上发现问题,因此我们将不胜感激。
答案 0 :(得分:1)
Task
是async
方法中没有返回值的返回类型。
或者,换句话说,async
将T
的值包装到Task<T>
中(或者将void
的返回值包装到Task
中),而{{1} }解开这些值。由于await
返回Credit
,因此表达式Task
的类型为Checkout.Credit(transaction)
,表达式Task
的类型为await Checkout.Credit(transaction)
。并且您无法将void
分配给void
;那就是编译器错误在说什么。
要解决此问题,请提供您的var teste
方法返回类型。特别是:
async
在旁注中,这很奇怪:
public static async Task<HttpResponseMessage> Credit(object data) =>
await client.PostAsync(url, data);
通常,如果您有一个public string Post(string url, object data) => ...;
public Task<HttpResponseMessage> PostAsync(string url, object data) => ...;
和一个Method
,其中MethodAsync
的返回类型为Method
,那么TResult
的返回类型为{{ 1}},而不是MethodAsync
。更自然的API可能是这样的:
Task<TResult>