【问题标题】:Consuming Web API from MVC4 controller?从 MVC4 控制器使用 Web API?
【发布时间】:2013-08-04 03:42:10
【问题描述】:

我目前在一个网站上工作,并且我按照具有存储库和管理器的存储库模式很好地分离了关注点。现在,我正在尝试实现一个 Web API,因为将来能够从各种客户端使用它,我将从中受益匪浅。由于我对 REST 服务相当陌生,因此我无法正确使用 MVC4 应用程序中的服务使用我的 Web API,然后在我的 MVC 控制器中使用该服务。我不想在每次调用 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
}

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

【问题讨论】:

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


    【解决方案1】:

    看看这里的实现:https://github.com/NBusy/NBusy.SDK/blob/master/src/NBusy.Client/Resources/Messages.cs

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

    【讨论】:

    • 这正是我想要的。好吧,至少是它的开始。非常感谢。还有一个问题,希望你能帮我回答。我是否必须单独运行我的 API 才能正常工作?还是主持?我至少 80% 确定我应该能够运行我的整个解决方案(包括 MVC4 应用程序和 WebApi 的)并且能够正确地使用 API?
    • 不,一点也不。我需要为该特定项目将后端与前端分开,但没有什么能阻止您在同一个项目中同时拥有 API 和 MVC。
    • 好的,我会再看看你的项目。因此,您是说通过将 MVC 项目作为启动项目运行我的解决方案应该足以访问 API?
    【解决方案2】:

    您可能想要创建一个静态类,我创建了一个单独的类库,以便在可能想要使用 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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-18
      • 2013-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多