从MVC4控制器中使用Web API?

时间:2013-08-04 03:42:11

标签: rest asp.net-mvc-4 asp.net-web-api

我目前正在一个网站上工作,并且在存储库模式与存储库和管理器之后,我对问题进行了很好的分离。现在,我正在尝试实现一个Web API,因为我将来可以从各种客户端使用它,从而大大受益。由于我对REST服务还不熟悉,因此我无法使用正确的程序从我的MVC4应用程序中的服务中使用我的Web API,然后在我的MVC控制器中使用该服务。我不想在每次调用API时都使用knockout。

我的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
}

我知道这是可能的,因为我已经看到它在一些工作场所完成但是很难找到关于此的文章,我只找到了解释如何通过淘汰消费web API的文章。任何帮助或提示将不胜感激。

2 个答案:

答案 0 :(得分:1)

在这里查看实施:https://github.com/NBusy/NBusy.SDK/blob/master/src/NBusy.Client/Resources/Messages.cs

它基本上使用HttpClient类来使用Web API。但需要注意的是,所有响应都包含在该示例中的自定义HttpResponse类中。您不需要这样做,只需将检索到的DTO对象用作返回类型或原始HttpResponseMessage类。

答案 1 :(得分: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);
    }
}