4

我目前在一个网站上工作,并且按照存储库模式与存储库和管理器进行了很好的关注点分离。现在,我正在尝试实现一个 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 的文章。任何帮助或提示将不胜感激。

4

2 回答 2

1

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

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

于 2013-08-04T12:16:40.553 回答
1

您可能想要创建一个静态类,我创建了一个单独的类库以跨可能想要使用 API 的解决方案使用。

注意:我使用 RestSharp 进行 POST 和 PUT 操作,因为我无法使用常规HttpClient的 SSL 让它们工作。正如您在这个问题中看到的那样。

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);
    }
}
于 2013-08-04T16:12:57.483 回答