2014-11-04 95 views
1

我正在尝试为C#中的API调用构建可重用模块。我想用这几个不同的API。但是我无法动态地将我的数据类作为变量传递给处理API调用的函数。例如,我打电话给两个完全不同的API,我们将它们称为“Api#1”和“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); 

试图在最后一行时,我得到一个错误。 “无法找到类型或名称空间名称'apiModel'(您是否缺少using指令或程序集引用?)”。我尝试了其他的东西,但这是最接近我的版本,所以这是我发布的版本。

所以我不确定如何做到这一点,或者也许有更好的方法。我很感激任何反馈,如果有必要,我们很乐意澄清。提前致谢。

+0

这不会帮助你的设计问题,但你得到这个错误的原因是因为'apiModel'不是一个类型,它是一个对象。试试'apiModel.GetType()'。 (我不是100%肯定会起作用) – MikeH 2014-11-04 21:22:06

+2

如果你能得到这个编译和书面工作,接下来会发生什么?在编译时,你仍然不知道'result'变量指向的对象的类型,所以你不能对它做任何有意义的事情。 – Jay 2014-11-04 21:30:03

+0

@MikeH谢谢你,我最终声明'输入apiModel'而不是'object apiModel'。 ''apiModel.GetType()'没有给我我想要的东西。 – RJD 2014-11-05 15:57:24

回答

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向这虽然之前更改了一些你的代码。