2013-08-04 94 views
4

我目前正在一個網站上工作,並且在存儲庫模式與存儲庫和管理員之後,我對問題進行了很好的分離。現在,我試圖實現一個Web API,因爲我將來可以從各種客戶端使用它,從中受益匪淺。由於我對REST服務相當陌生,因此無法正確使用我的MVC4應用程序中服務的Web API,然後在我的MVC控制器中使用該服務。我不想在每次調用API時都使用knockout。從MVC4控制器消費Web API?

我的Web的API看起來像這樣(簡化):

public class UserController : ApiController 
{ 
    private readonly IUserManager _manager; 

    public UserController(IUserManager manager) 
    { 
     this._manager = manager; 
    } 

    // GET api/user 
    public IEnumerable<User> Get() 
    { 
     return _manager.GetAll(); 
    } 

    // GET api/user/5 
    public User Get(int id) 
    { 
     return _manager.GetById(id); 
    } 

    // POST api/user 
    public void Post(User user) 
    { 
     _manager.Add(user); 
    } 

    // PUT api/user/5 
    public void Put(User user) 
    { 
     _manager.Update(user); 
    } 

    // DELETE api/user/5 
    public void Delete(User user) 
    { 
     _manager.Delete(user); 
    } 
} 

我基本上是想創建一個服務消耗我的Web API這樣:

public class UserService : IUserService 
{ 
    ....Implement something to get,post,put,and delete using the api. 
} 

這樣的話,我可以使用它在我的mvc控制器中:

public class UserController: Controller 
{ 
    private readonly IUserService _userService; 

    public UserController(IUserService userService) 
    { 
     this._userService = userService; 
    } 
    //And then I will be able to communicate with my WebAPI from my MVC controller 
} 

我知道這是可能的,因爲我已經看到它在一些workpl中完成王牌,但很難找到有關這方面的文章,我只找到解釋如何通過淘汰賽消費Web API的文章。任何幫助或提示將不勝感激。

回答

1

看一看執行看過來:https://github.com/NBusy/NBusy.SDK/blob/master/src/NBusy.Client/Resources/Messages.cs

它主要利用HttpClient類的使用Web API。但有一點需要注意,所有的答案都會包含在該樣本中的自定義類HttpResponse中。您不需要這樣做,只需使用檢索的DTO對象作爲返回類型或原始類別即可。

+0

這就是我正在尋找的。那麼,至少從一開始就是這樣。非常感謝你。還有一個問題,我希望你能回答我。我是否必須單獨運行我的API才能正常工作?或主持?我至少有80%確定我應該能夠運行我的整個解決方案(包括MVC4應用程序和WebApi's),並且能夠正確匹配API? – Eddie

+0

不,完全沒有。我需要將該後端從該特定項目的前端分離出來,但無法阻止您在同一個項目中同時擁有API和MVC。 –

+0

好的,我會再看看你的項目。所以你是說,通過運行我的解決方案** MVC項目作爲啓動項目**應該足以能夠擊中API? – Eddie

1

您可能想要創建一個靜態類,我創建了一個單獨的類庫以便在可能想要使用該API的解決方案中使用。

注意:我使用RestSharp進行POST和PUT操作,因爲我無法通過SSL使用常規的HttpClient來使它們工作。正如你可以在question中看到的那樣。

internal static class Container 
{ 
    private static bool isInitialized; 
    internal static HttpClient Client { get; set; } 
    internal static RestClient RestClient { get; set; } 

    /// <summary> 
    /// Verifies the initialized. 
    /// </summary> 
    /// <param name="throwException">if set to <c>true</c> [throw exception].</param> 
    /// <returns> 
    ///  <c>true</c> if it has been initialized; otherwise, <c>false</c>. 
    /// </returns> 
    /// <exception cref="System.InvalidOperationException">Service must be initialized first.</exception> 
    internal static bool VerifyInitialized(bool throwException = true) 
    { 
     if (!isInitialized) 
     { 
      if (throwException) 
      { 
       throw new InvalidOperationException("Service must be initialized first."); 
      } 
     } 

     return true; 
    } 

    /// <summary> 
    /// Initializes the Service communication, all methods throw a System.InvalidOperationException if it hasn't been initialized. 
    /// </summary> 
    /// <param name="url">The URL.</param> 
    /// <param name="connectionUserName">Name of the connection user.</param> 
    /// <param name="connectionPassword">The connection password.</param> 
    internal static void Initialize(string url, string connectionUserName, string connectionPassword) 
    { 
     RestClient = new RestClient(url); 
     if (connectionUserName != null && connectionPassword != null) 
     { 
      HttpClientHandler handler = new HttpClientHandler 
      { 
       Credentials = new NetworkCredential(connectionUserName, connectionPassword) 
      }; 
      Client = new HttpClient(handler); 
      RestClient.Authenticator = new HttpBasicAuthenticator(connectionUserName, connectionPassword); 
     } 
     else 
     { 
      Client = new HttpClient(); 
     } 
     Client.BaseAddress = new Uri(url); 
     isInitialized = true; 
    } 
} 

public static class UserService 
{ 
    public static void Initialize(string url = "https://serverUrl/", string connectionUserName = null, string connectionPassword = null) 
    { 
     Container.Initialize(url, connectionUserName, connectionPassword); 
    } 

    public static async Task<IEnumerable<User>> GetServiceSites() 
    { 
     // RestSharp example 
     Container.VerifyInitialized(); 
     var request = new RestRequest("api/Users", Method.GET); 
     request.RequestFormat = DataFormat.Json; 
     var response = await Task.Factory.StartNew(() => { return Container.RestClient.Execute<List<User>>(request); }).ConfigureAwait(false); 
     return response.Data; 
     // HttpClient example 
     var response = await Container.Client.GetAsync("api/Users/").ConfigureAwait(false); 
     return await response.Content.ReadAsAsync<IEnumerable<User>>().ConfigureAwait(false); 
    } 

    public static async Task<User> Get(int id) 
    { 
     Container.VerifyInitialized(); 
     var request = new RestRequest("api/Users/" + id, Method.GET); 
     var response = await Task.Factory.StartNew(() => { return Container.RestClient.Execute<User>(request); }).ConfigureAwait(false); 
     return response.Data; 
    } 

    public static async Task Put(int id, User user) 
    { 
     Container.VerifyInitialized(); 
     var request = new RestRequest("api/Users/" + id, Method.PATCH); 
     request.RequestFormat = DataFormat.Json; 
     request.AddBody(user); 
     var response = await Task.Factory.StartNew(() => { return Container.RestClient.Execute(request); }).ConfigureAwait(false); 
    } 

    public static async Task Post(User user) 
    { 
     Container.VerifyInitialized(); 
     var request = new RestRequest("api/Users", Method.POST); 
     request.RequestFormat = DataFormat.Json; 
     request.AddBody(user); 
     var response = await Task.Factory.StartNew(() => { return Container.RestClient.Execute(request); }).ConfigureAwait(false); 
    } 

    public static async Task Delete(int id) 
    { 
     Container.VerifyInitialized(); 
     var request = new RestRequest("api/Users/" + id, Method.DELETE); 
     var response = await Task.Factory.StartNew(() => { return Container.RestClient.Execute(request); }).ConfigureAwait(false); 
    } 
}