API请求中的无效返回

时间:2019-06-05 22:16:50

标签: c# dotnet-httpclient

在此处创建客户端和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请求进行单元测试就像一个魅力一样,但是我无法在我的项目结构上发现问题,因此我们将不胜感激。

1 个答案:

答案 0 :(得分:1)

Taskasync方法中没有返回值的返回类型

或者,换句话说,asyncT的值包装到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>