3

我有一个我创建的用于简化使用 HttpClient 调用的方法。它使用 HttpReponse.Content.ReadAsAsync().Result 方法从 API 获取响应。

这一切都很好。我的方法看起来像这样:

    public static T ExecuteAPIGetRequest<T>(string url, Dictionary<string, string> parameters)
    {

        HttpClient client = new HttpClient();
        //basic authentication

        var t = new object();
        string baseURL =  "myurl"; 

        //Execute request
        HttpResponseMessage response = client.GetAsync(baseURL).Result;

        if (response.IsSuccessStatusCode)
        {
            return response.Content.ReadAsAsync<T>().Result;  
        }
        else
        {
            return (T)t;
        }
    }

我的问题是,如果查询失败,它需要返回一个空类型的 T。如果它是我编写的自定义类,这很好,但它不适用于字符串或字符串 [] 等对象。有任何想法吗?

干杯

NCBL

4

2 回答 2

7

尝试返回default(T)

if (response.IsSuccessStatusCode)
{
    return response.Content.ReadAsAsync<T>().Result;  
}
else
{
    return default(T);
}

default将返回null引用类型,并将数值归零int,等。以及 custom和double的相应默认值。structenum

Daniel 好心地指出了一个问题:如果对于引用类型,您想要返回默认对象而不是null,您应该定义泛型约束new T()T现在您可以使用对无参数构造函数的调用来实例化类型对象。完整方法如下:

public static T ExecuteAPIGetRequest<T>(string url, 
                                        Dictionary<string, string> parameters)
                                                                   where T : new()
{

    HttpClient client = new HttpClient();

    //basic authentication

    string baseURL =  "myurl"; 

    HttpResponseMessage response = client.GetAsync(baseURL).Result;

    if (response.IsSuccessStatusCode)
    {
        return response.Content.ReadAsAsync<T>().Result;  
    }
    else
    {
        return new T(); //returns an instance, not null
    }
}

现在您将返回引用类型的默认对象,而不是 null。开放类型T只能接受类型,默认有构造函数(不带参数)

于 2013-04-02T14:15:00.323 回答
0

我可以建议您考虑这样的方法吗....

class Program
{
    static void Main(string[] args)
    {

        var client = new HttpClient();

        //basic authentication

        string baseURL = "myurl";

        var link = Link<Foo>.Create(baseURL);

        var response = client.SendAsync(link.CreateRequest()).Result;

        var myfoo = link.ProcessResponse(response);

    }

}


public class Link<T>
{
    public Uri Target { get; set; }

    public static Link<T> Create(string url)
    {
        return new Link<T>() {Target = new Uri(url)};
    }

    public HttpRequestMessage CreateRequest()
    {
        return new HttpRequestMessage() {RequestUri = Target};
    }   

    public T ProcessResponse(HttpResponseMessage response)
    {
        if (response.IsSuccessStatusCode)
        {
            return response.Content.ReadAsAsync<T>().Result;
        }
        else
        {
            return new T(); //returns an instance, not null
        }
    }
}

public class Foo
{

}

通过将创建链接的机制封装到静态工厂方法中并将响应处理封装到 ProcessResponse 方法中,您可以获得类似级别的可重用性,但您也可以获得重用相同 HttpClient 的好处。这使您可以实际利用 DefaultRequestHeaders 并且它将阻止 HttpClient 在处理连接时继续关闭连接。

此外,通过避免将异步调用包装在同步方法中,您可以让调用代码决定是阻止结果还是异步处理它。您当前使用 .Result 的方式可能会在某些时候遇到死锁问题。

这种创建 Link 类以封装与取消引用 URL 有关的特定行为的技术非常有用。添加可用于填写 URI 模板的参数很容易。您还可以使用它来处理请求正文。

于 2013-04-04T02:06:52.197 回答