2014-12-07 46 views
2

在我的MVC应用程序中,我做了很多需要几行代码的Web API调用。我想创建一个集中的API调用方法,只需将一些简单的参数传递给它,例如呼叫类型(GET,POST等),Url等。想要集中调用我的Web API的代码

我需要帮助的是在每种情况下,我将返回不同的对象类型,例如Employee,List <Project>等。如何返回不同的对象类型?

另一个问题是,如果我想进行POST或PUT调用,我会将不同类型的对象传入我的集中式API调用方法。再次,我有同样的问题,我必须能够接受不同的对象类型。

我想,我可以只传递Json对象,但我不确定这是正确的方法,还是有更好的方法。我确信其他人已经试图集中他们的Web API调用代码。

*更新* 这是我迄今为止,但我需要更多的帮助。我如何返回结果?

public static async Task<object> GetApiCall(string apiActionUrl) 
{ 
    using (var client = new HttpClient()) 
    { 
     client.BaseAddress = new Uri("http://myApiBaseUrl"); 
     client.DefaultRequestHeaders.Accept.Clear(); 
     client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

     HttpResponseMessage response = await client.GetAsync(apiActionUrl); 
     if (response.IsSuccessStatusCode) 
     { 
     var result = response.Content.ReadAsStringAsync().Result; 
     } 
    } 
} 
+0

可以显示您想要集中的代码的2个样本?你也许可以为你的代码创建一个基类,或者创建一个call handler类,但是在这两种情况下,你都必须泛型传递参数和返回类型。 – 2014-12-07 06:20:22

+0

刚刚更新了我原来的帖子,并附上了我提出的示例代码。我从来没有返回过一个通用对象,所以我试图了解我是如何做到这一点的。我在代码中不清楚的其他部分是,当我从Web API收到错误响应时。那么我会返回什么? – Sam 2014-12-07 06:27:11

+0

太棒了,让我给你写一些代码,并在这里发布它。 – 2014-12-07 06:36:55

回答

1

试试这个:这是一个起点,你可以在此基础上构建,但想法是ApiCaller是一个实现IApiCaller接口的类(所以你可以在后面模拟它),并且这个类使用相同的方法启动HttpClient options/headers,并且该方法将使用/处理此HttpClient以连接到服务器,并且每个方法在调用者调用方法(如Get)时定义返回类型T.

public interface IApiCaller 
{ 
    Task<T> Get<T>(string apiActionUrl); 
} 

public class ApiCaller : IApiCaller 
{ 
    private const string ApiBaseUrl = "http://myApiBaseUrl"; 

    public async Task<T> Get<T>(string apiActionUrl) 
    { 
     using (var client = GetHttpClient()) 
     { 
      var response = await client.GetAsync(apiActionUrl); 
      if (response.IsSuccessStatusCode) 
      { 
       var jsonString = response.Content.ReadAsStringAsync().Result; 
       return JsonConvert.DeserializeObject<T>(jsonString); 
      } 
     } 

     return default(T); 
    } 

    private static HttpClient GetHttpClient() 
    { 
     var client = new HttpClient 
     { 
      BaseAddress = new Uri(ApiBaseUrl), 
     }; 

     client.DefaultRequestHeaders.Accept.Clear(); 
     client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

     return client; 
    } 
} 

你可以使用这个类是这样的:

public class SomeMvcController : Controller 
{ 
    private readonly IApiCaller _apiCaller; 

    // use this if you don't want to rely on Dependency Injection, OR 
    // if you don't use Ioc container for now.  
    public SomeClass(): this(new ApiCaller()) 
    { 
    } 

    public SomeClass(IApiCaller apiCaller) 
    { 
     _apiCaller = apiCaller; 
    } 

    public async Task<string> GetStringFromWebApi() 
    { 
     string result = await _apiCaller.Get<string>("myApiUrl"); 

     return result; 
    } 
} 

希望有所帮助。

+0

这段代码看起来不错而且精细,但有些东西是超出我的水平的。你会友善地帮我理解吗?首先,我无法从需要进行API调用的MVC操作方法调用它。我试过MyApp.ApiCaller.Get(),但所有intellisense给我的是Equals和ReferenceEquals。我没有看到Get方法。我也不清楚你为什么从IApiCaller接口继承。它的优点是什么? – Sam 2014-12-07 07:18:45

+0

1-以前您的GetApiCaller方法是一种静态方法,但我已将其更改为实例方法,这意味着您必须通过新方法初始化ApiCaller类。我使用Interface IApiCaller,所以你可以模拟这个类进行单元测试,谷歌“Moq库”或“C#单元测试”以更多地了解单元测试。 3,您的MVC控制器将注入IApiCaller接口,您可以使用像Autofac这样的IoC容器来设置依赖关系。这是足够清楚还是需要更多? – 2014-12-07 07:29:41

+0

我有点清楚,但我不想花太多时间。你一直非常有帮助!如果你不介意的话,我想再问一个问题。把它变成一个静态类不是更好,这样我就不必每次创建一个ApiCaller类的新实例,因为我需要创建一个API调用? – Sam 2014-12-07 07:40:06

0

返回一个对象或使用动态返回类型。

+0

我可以使用更多的帮助。我如何返回“结果”。另外,如果我从Web API调用中收到错误,那么我该如何返回? – Sam 2014-12-07 06:21:28

相关问题