我正在尝试为C#中的API调用构建一个可重用的模块。我想将它用于几种不同的API。但我无法将我的数据类作为变量动态传递给处理API调用的函数。
所以,让我们说,例如,我称之为两个完全不同的API,我们称之为#34; Api#1"和#34; Api#2"。我有以下课程:
// This is the format of the response from Api #1 GET
public class Api01Get
{
public int orderId { get; set; }
public DateTime orderDate { get; set; }
}
// This is the format of the response from Api #2 GET
public class Api02Get
{
public bool isGreen { get; set; }
public string name { get; set; }
}
这是对我的功能的调用。如果我直接使用我的一个数据类,它可以正常工作:
var result = CallAPI<Api02Get>(baseAddress, requestUri);
但这并不能让我获得灵活性。
这是我的函数的定义(我在这里省略了其他不影响事情的参数):
private async Task<TResult> CallAPI<TResult>(Uri baseAddress, string requestUri)
{
using (var client = new HttpClient())
{
client.BaseAddress = baseAddress;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = new HttpResponseMessage();
response = await client.GetAsync(requestUri);
if (response.IsSuccessStatusCode)
{
TResult result = await response.Content.ReadAsAsync<TResult>();
}
}
// do other stuff...
return result;
}
现在这就是我被挂断的地方。我必须以不正确的方式思考这个问题,但我想要做的就是这样的事情,例如:
object apiModel;
switch (whichAPI)
{
case "API_01_GET":
apiModel = new Api01Get();
break;
case "API_02_GET":
apiModel = new Api02Get();
break;
// Other cases...
default:
break;
}
var result = CallAPI<apiModel>(baseAddress, requestUri);
尝试最后一行时出错。 &#34;类型或命名空间名称&#39; apiModel&#39;找不到(你是否错过了使用指令或汇编引用?)&#34;。我尝试了其他的东西,但这个版本似乎让我最接近,所以这就是我发布的内容。
所以我不确定如何实现这一点,或者可能有一个更好的方法。我感谢任何反馈,如果有必要,我很乐意澄清。提前谢谢。
答案 0 :(得分:0)
不幸的是,如果没有额外的反射来动态调用CallAPI<T>
,你就不能在这里使用泛型。
幸运的是,HttpContentExtensions有额外的重载,允许您传入Type
。您只需要重载您的方法并对ReadAsAsync
稍作调整。
private async Task<object> CallAPI(Uri baseAddress, string requestUri, Type apiType)
{
using (var client = new HttpClient())
{
....
if (response.IsSuccessStatusCode)
{
object result = await response.Content.ReadAsAsync(apiType);
}
}
....
return result;
}
您可能仍需要在此之前更改部分代码,因为您仍然遇到object
。